1
0
mirror of https://github.com/systemd/systemd synced 2026-03-14 00:54:46 +01:00

Compare commits

..

No commits in common. "4e947bd04944e58df4103eee4cb8180b5008f143" and "f813b62316395205f4c744cde43885081b5f88ae" have entirely different histories.

19 changed files with 144 additions and 393 deletions

View File

@ -195,7 +195,6 @@
<xi:include href="standard-options.xml" xpointer="help" /> <xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" /> <xi:include href="standard-options.xml" xpointer="version" />
<xi:include href="standard-options.xml" xpointer="json" />
</variablelist> </variablelist>
</refsect1> </refsect1>

View File

@ -58,7 +58,6 @@ node /org/freedesktop/hostname1 {
in b interactive); in b interactive);
GetProductUUID(in b interactive, GetProductUUID(in b interactive,
out ay uuid); out ay uuid);
Describe(out s UNNAMED);
properties: properties:
readonly s Hostname = '...'; readonly s Hostname = '...';
readonly s StaticHostname = '...'; readonly s StaticHostname = '...';
@ -119,8 +118,6 @@ node /org/freedesktop/hostname1 {
<variablelist class="dbus-method" generated="True" extra-ref="GetProductUUID()"/> <variablelist class="dbus-method" generated="True" extra-ref="GetProductUUID()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Describe()"/>
<variablelist class="dbus-property" generated="True" extra-ref="Hostname"/> <variablelist class="dbus-property" generated="True" extra-ref="Hostname"/>
<variablelist class="dbus-property" generated="True" extra-ref="StaticHostname"/> <variablelist class="dbus-property" generated="True" extra-ref="StaticHostname"/>
@ -235,17 +232,6 @@ node /org/freedesktop/hostname1 {
<citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>3</manvolnum></citerefentry> <citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for that. For more information on these files and syscalls see the respective man pages.</para> for that. For more information on these files and syscalls see the respective man pages.</para>
<para><varname>KernelName</varname>, <varname>KernelRelease</varname>, and
<varname>KernelVersion</varname> expose the kernel name (e.g. <literal>Linux</literal>), release
(e.g. <literal>5.0.0-11</literal>), and version (i.e. the build number, e.g. <literal>#11</literal>) as
reported by <citerefentry project="man-pages"><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
<varname>OperatingSystemPrettyName</varname>, <varname>OperatingSystemCPEName</varname>, and
<varname>HomeURL</varname> expose the <varname>PRETTY_NAME=</varname>, <varname>CPE_NAME=</varname> and
<varname>HOME_URL=</varname> fields from
<citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>. The
purpose of those properties is to allow remote clients to access this information over D-Bus. Local
clients can access the information directly.</para>
<refsect2> <refsect2>
<title>Methods</title> <title>Methods</title>
@ -275,12 +261,22 @@ node /org/freedesktop/hostname1 {
<citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry> for <citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
the semantics of those settings.</para> the semantics of those settings.</para>
<para><function>GetProductUUID()</function> returns the "product UUID" as exposed by the kernel based <para><function>GetProductUUID()</function> returns the "product uuid" as exposed by the kernel based
on DMI information in <filename>/sys/class/dmi/id/product_uuid</filename>. Reading the file directly on DMI information in <filename>/sys/class/dmi/id/product_uuid</filename>. Reading the file directly
requires root privileges, and this method allows access to unprivileged clients through the polkit requires root privileges, and this method allows access to unprivileged clients through the polkit
framework.</para> framework.</para>
<para><function>Describe()</function> returns a JSON representation of all properties in one.</para> <para><varname>KernelName</varname>, <varname>KernelRelease</varname>, and
<varname>KernelVersion</varname> expose the kernel name (e.g. <literal>Linux</literal>), release
(e.g. <literal>5.0.0-11</literal>), and version (i.e. the build number, e.g. <literal>#11</literal>) as
reported by
<citerefentry project="man-pages"><refentrytitle>uname</refentrytitle><manvolnum>2</manvolnum></citerefentry>.
<varname>OperatingSystemPrettyName</varname>, <varname>OperatingSystemCPEName</varname>, and
<varname>HomeURL</varname> expose the <varname>PRETTY_NAME=</varname>, <varname>CPE_NAME=</varname> and
<varname>HOME_URL=</varname> fields from
<citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>. The
purpose of those properties is to allow remote clients to access this information over D-Bus. Local
clients can access the information directly.</para>
</refsect2> </refsect2>
<refsect2> <refsect2>

View File

@ -376,12 +376,7 @@
of the <filename>function_id</filename> device attribute. This attribute is now used to build the of the <filename>function_id</filename> device attribute. This attribute is now used to build the
<varname>ID_NET_NAME_SLOT</varname>. Before that, all slot names were parsed as decimal <varname>ID_NET_NAME_SLOT</varname>. Before that, all slot names were parsed as decimal
numbers, which could either result in an incorrect value of the <varname>ID_NET_NAME_SLOT</varname> numbers, which could either result in an incorrect value of the <varname>ID_NET_NAME_SLOT</varname>
property or none at all.</para> property or none at all.</para></listitem>
<para>Some firmware and hypervisor implementations report unreasonable high numbers for the onboard
index. To prevent the generation of bogus onbard interface names, index numbers greater than 16381
(2^14-1) were ignored. For s390 PCI devices index values up to 65535 (2^16-1) are valid. To account
for that, the limit is increased to now 65535.</para></listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>

View File

@ -17,9 +17,7 @@
#include "format-table.h" #include "format-table.h"
#include "hostname-setup.h" #include "hostname-setup.h"
#include "hostname-util.h" #include "hostname-util.h"
#include "json.h"
#include "main-func.h" #include "main-func.h"
#include "parse-argument.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "spawn-polkit-agent.h" #include "spawn-polkit-agent.h"
#include "terminal-util.h" #include "terminal-util.h"
@ -32,7 +30,6 @@ static char *arg_host = NULL;
static bool arg_transient = false; static bool arg_transient = false;
static bool arg_pretty = false; static bool arg_pretty = false;
static bool arg_static = false; static bool arg_static = false;
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
typedef struct StatusInfo { typedef struct StatusInfo {
const char *hostname; const char *hostname;
@ -320,37 +317,6 @@ static int show_all_names(sd_bus *bus) {
static int show_status(int argc, char **argv, void *userdata) { static int show_status(int argc, char **argv, void *userdata) {
sd_bus *bus = userdata; sd_bus *bus = userdata;
int r;
if (arg_json_format_flags != JSON_FORMAT_OFF) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
const char *text = NULL;
r = sd_bus_call_method(
bus,
"org.freedesktop.hostname1",
"/org/freedesktop/hostname1",
"org.freedesktop.hostname1",
"Describe",
&error,
&reply,
NULL);
if (r < 0)
return log_error_errno(r, "Could not get description: %s", bus_error_message(&error, r));
r = sd_bus_message_read(reply, "s", &text);
if (r < 0)
return bus_log_parse_error(r);
r = json_parse(text, 0, &v, NULL, NULL);
if (r < 0)
return log_error_errno(r, "Failed to parse JSON: %m");
json_variant_dump(v, arg_json_format_flags, NULL, NULL);
return 0;
}
if (arg_pretty || arg_static || arg_transient) { if (arg_pretty || arg_static || arg_transient) {
const char *attr; const char *attr;
@ -523,8 +489,6 @@ static int help(void) {
" --transient Only set transient hostname\n" " --transient Only set transient hostname\n"
" --static Only set static hostname\n" " --static Only set static hostname\n"
" --pretty Only set pretty hostname\n" " --pretty Only set pretty hostname\n"
" --json=pretty|short|off\n"
" Generate JSON output\n"
"\nSee the %s for details.\n", "\nSee the %s for details.\n",
program_invocation_short_name, program_invocation_short_name,
ansi_highlight(), ansi_highlight(),
@ -545,8 +509,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_NO_ASK_PASSWORD, ARG_NO_ASK_PASSWORD,
ARG_TRANSIENT, ARG_TRANSIENT,
ARG_STATIC, ARG_STATIC,
ARG_PRETTY, ARG_PRETTY
ARG_JSON,
}; };
static const struct option options[] = { static const struct option options[] = {
@ -558,11 +521,10 @@ static int parse_argv(int argc, char *argv[]) {
{ "host", required_argument, NULL, 'H' }, { "host", required_argument, NULL, 'H' },
{ "machine", required_argument, NULL, 'M' }, { "machine", required_argument, NULL, 'M' },
{ "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD }, { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
{ "json", required_argument, NULL, ARG_JSON },
{} {}
}; };
int c, r; int c;
assert(argc >= 0); assert(argc >= 0);
assert(argv); assert(argv);
@ -603,13 +565,6 @@ static int parse_argv(int argc, char *argv[]) {
arg_ask_password = false; arg_ask_password = false;
break; break;
case ARG_JSON:
r = parse_json_argument(optarg, &arg_json_format_flags);
if (r <= 0)
return r;
break;
case '?': case '?':
return -EINVAL; return -EINVAL;

View File

@ -20,7 +20,6 @@
#include "hostname-setup.h" #include "hostname-setup.h"
#include "hostname-util.h" #include "hostname-util.h"
#include "id128-util.h" #include "id128-util.h"
#include "json.h"
#include "main-func.h" #include "main-func.h"
#include "missing_capability.h" #include "missing_capability.h"
#include "nscd-flush.h" #include "nscd-flush.h"
@ -41,8 +40,6 @@
#define VALID_DEPLOYMENT_CHARS (DIGITS LETTERS "-.:") #define VALID_DEPLOYMENT_CHARS (DIGITS LETTERS "-.:")
/* Properties we cache are indexed by an enum, to make invalidation easy and systematic (as we can iterate
* through them all, and they are uniformly strings). */
enum { enum {
/* Read from /etc/hostname */ /* Read from /etc/hostname */
PROP_STATIC_HOSTNAME, PROP_STATIC_HOSTNAME,
@ -54,6 +51,9 @@ enum {
PROP_DEPLOYMENT, PROP_DEPLOYMENT,
PROP_LOCATION, PROP_LOCATION,
PROP_HARDWARE_VENDOR,
PROP_HARDWARE_MODEL,
/* Read from /etc/os-release (or /usr/lib/os-release) */ /* Read from /etc/os-release (or /usr/lib/os-release) */
PROP_OS_PRETTY_NAME, PROP_OS_PRETTY_NAME,
PROP_OS_CPE_NAME, PROP_OS_CPE_NAME,
@ -449,41 +449,6 @@ static int context_write_data_machine_info(Context *c) {
return 0; return 0;
} }
static int get_dmi_data(const char *database_key, const char *regular_key, char **ret) {
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
_cleanup_free_ char *b = NULL;
const char *s = NULL;
int r;
r = sd_device_new_from_syspath(&device, "/sys/class/dmi/id");
if (r < 0)
return log_debug_errno(r, "Failed to open /sys/class/dmi/id device, ignoring: %m");
if (database_key)
(void) sd_device_get_property_value(device, database_key, &s);
if (!s && regular_key)
(void) sd_device_get_property_value(device, regular_key, &s);
if (s) {
b = strdup(s);
if (!b)
return -ENOMEM;
}
if (ret)
*ret = TAKE_PTR(b);
return !!s;
}
static int get_hardware_vendor(char **ret) {
return get_dmi_data("ID_VENDOR_FROM_DATABASE", "ID_VENDOR", ret);
}
static int get_hardware_model(char **ret) {
return get_dmi_data("ID_MODEL_FROM_DATABASE", "ID_MODEL", ret);
}
static int property_get_hardware_vendor( static int property_get_hardware_vendor(
sd_bus *bus, sd_bus *bus,
const char *path, const char *path,
@ -492,11 +457,20 @@ static int property_get_hardware_vendor(
sd_bus_message *reply, sd_bus_message *reply,
void *userdata, void *userdata,
sd_bus_error *error) { sd_bus_error *error) {
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
const char *hardware_vendor = NULL;
int r;
_cleanup_free_ char *vendor = NULL; r = sd_device_new_from_syspath(&device, "/sys/class/dmi/id");
if (r < 0) {
log_warning_errno(r, "Failed to open /sys/class/dmi/id device, ignoring: %m");
return sd_bus_message_append(reply, "s", NULL);
}
(void) get_hardware_vendor(&vendor); if (sd_device_get_property_value(device, "ID_VENDOR_FROM_DATABASE", &hardware_vendor) < 0)
return sd_bus_message_append(reply, "s", vendor); (void) sd_device_get_property_value(device, "ID_VENDOR", &hardware_vendor);
return sd_bus_message_append(reply, "s", hardware_vendor);
} }
static int property_get_hardware_model( static int property_get_hardware_model(
@ -507,11 +481,20 @@ static int property_get_hardware_model(
sd_bus_message *reply, sd_bus_message *reply,
void *userdata, void *userdata,
sd_bus_error *error) { sd_bus_error *error) {
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
const char *hardware_model = NULL;
int r;
_cleanup_free_ char *model = NULL; r = sd_device_new_from_syspath(&device, "/sys/class/dmi/id");
if (r < 0) {
log_warning_errno(r, "Failed to open /sys/class/dmi/id device, ignoring: %m");
return sd_bus_message_append(reply, "s", NULL);
}
(void) get_hardware_model(&model); if (sd_device_get_property_value(device, "ID_MODEL_FROM_DATABASE", &hardware_model) < 0)
return sd_bus_message_append(reply, "s", model); (void) sd_device_get_property_value(device, "ID_MODEL", &hardware_model);
return sd_bus_message_append(reply, "s", hardware_model);
} }
static int property_get_hostname( static int property_get_hostname(
@ -565,46 +548,13 @@ static int property_get_default_hostname(
void *userdata, void *userdata,
sd_bus_error *error) { sd_bus_error *error) {
_cleanup_free_ char *hn = NULL; _cleanup_free_ char *hn = get_default_hostname();
hn = get_default_hostname();
if (!hn) if (!hn)
return log_oom(); return log_oom();
return sd_bus_message_append(reply, "s", hn); return sd_bus_message_append(reply, "s", hn);
} }
static void context_determine_hostname_source(Context *c) {
char hostname[HOST_NAME_MAX + 1] = {};
_cleanup_free_ char *fallback = NULL;
int r;
assert(c);
if (c->hostname_source >= 0)
return;
(void) get_hostname_filtered(hostname);
if (streq_ptr(hostname, c->data[PROP_STATIC_HOSTNAME]))
c->hostname_source = HOSTNAME_STATIC;
else {
/* If the hostname was not set by us, try to figure out where it came from. If we set it to
* the default hostname, the file will tell us. We compare the string because it is possible
* that the hostname was set by an older version that had a different fallback, in the
* initramfs or before we reexecuted. */
r = read_one_line_file("/run/systemd/default-hostname", &fallback);
if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to read /run/systemd/default-hostname, ignoring: %m");
if (streq_ptr(fallback, hostname))
c->hostname_source = HOSTNAME_DEFAULT;
else
c->hostname_source = HOSTNAME_TRANSIENT;
}
}
static int property_get_hostname_source( static int property_get_hostname_source(
sd_bus *bus, sd_bus *bus,
const char *path, const char *path,
@ -615,10 +565,36 @@ static int property_get_hostname_source(
sd_bus_error *error) { sd_bus_error *error) {
Context *c = userdata; Context *c = userdata;
int r;
assert(c); assert(c);
context_read_etc_hostname(c); context_read_etc_hostname(c);
context_determine_hostname_source(c);
if (c->hostname_source < 0) {
char hostname[HOST_NAME_MAX + 1] = {};
_cleanup_free_ char *fallback = NULL;
(void) get_hostname_filtered(hostname);
if (streq_ptr(hostname, c->data[PROP_STATIC_HOSTNAME]))
c->hostname_source = HOSTNAME_STATIC;
else {
/* If the hostname was not set by us, try to figure out where it came from. If we set
* it to the default hostname, the file will tell us. We compare the string because
* it is possible that the hostname was set by an older version that had a different
* fallback, in the initramfs or before we reexecuted. */
r = read_one_line_file("/run/systemd/default-hostname", &fallback);
if (r < 0 && r != -ENOENT)
log_warning_errno(r, "Failed to read /run/systemd/default-hostname, ignoring: %m");
if (streq_ptr(fallback, hostname))
c->hostname_source = HOSTNAME_DEFAULT;
else
c->hostname_source = HOSTNAME_TRANSIENT;
}
}
return sd_bus_message_append(reply, "s", hostname_source_to_string(c->hostname_source)); return sd_bus_message_append(reply, "s", hostname_source_to_string(c->hostname_source));
} }
@ -956,12 +932,28 @@ static int method_set_location(sd_bus_message *m, void *userdata, sd_bus_error *
static int method_get_product_uuid(sd_bus_message *m, void *userdata, sd_bus_error *error) { static int method_get_product_uuid(sd_bus_message *m, void *userdata, sd_bus_error *error) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
Context *c = userdata; Context *c = userdata;
bool has_uuid = false;
int interactive, r; int interactive, r;
sd_id128_t uuid; sd_id128_t uuid;
assert(m); assert(m);
assert(c); assert(c);
r = id128_read("/sys/class/dmi/id/product_uuid", ID128_UUID, &uuid);
if (r == -ENOENT)
r = id128_read("/sys/firmware/devicetree/base/vm,uuid", ID128_UUID, &uuid);
if (r < 0)
log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
"Failed to read product UUID, ignoring: %m");
else if (sd_id128_is_null(uuid) || sd_id128_is_allf(uuid))
log_debug("DMI product UUID " SD_ID128_FORMAT_STR " is all 0x00 or all 0xFF, ignoring.", SD_ID128_FORMAT_VAL(uuid));
else
has_uuid = true;
if (!has_uuid)
return sd_bus_error_set(error, BUS_ERROR_NO_PRODUCT_UUID,
"Failed to read product UUID from firmware.");
r = sd_bus_message_read(m, "b", &interactive); r = sd_bus_message_read(m, "b", &interactive);
if (r < 0) if (r < 0)
return r; return r;
@ -980,125 +972,11 @@ static int method_get_product_uuid(sd_bus_message *m, void *userdata, sd_bus_err
if (r == 0) if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
r = id128_get_product(&uuid);
if (r < 0) {
if (r == -EADDRNOTAVAIL)
log_debug_errno(r, "DMI product UUID is all 0x00 or all 0xFF, ignoring.");
else
log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
"Failed to read product UUID, ignoring: %m");
return sd_bus_error_set(error, BUS_ERROR_NO_PRODUCT_UUID,
"Failed to read product UUID from firmware.");
}
r = sd_bus_message_new_method_return(m, &reply); r = sd_bus_message_new_method_return(m, &reply);
if (r < 0) if (r < 0)
return r; return r;
r = sd_bus_message_append_array(reply, 'y', uuid.bytes, sizeof(uuid.bytes)); r = sd_bus_message_append_array(reply, 'y', &uuid, sizeof(uuid));
if (r < 0)
return r;
return sd_bus_send(NULL, reply, NULL);
}
static int method_describe(sd_bus_message *m, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *hn = NULL, *dhn = NULL, *in = NULL, *text = NULL, *vendor = NULL, *model = NULL;
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
sd_id128_t product_uuid = SD_ID128_NULL;
const char *chassis = NULL;
Context *c = userdata;
bool privileged;
struct utsname u;
int r;
assert(m);
assert(c);
r = bus_verify_polkit_async(
m,
CAP_SYS_ADMIN,
"org.freedesktop.hostname1.get-product-uuid",
NULL,
false,
UID_INVALID,
&c->polkit_registry,
NULL);
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
/* We ignore all authentication errors here, since most data is unprivileged, the one exception being
* the product ID which we'll check explicitly. */
privileged = r > 0;
context_read_etc_hostname(c);
context_read_machine_info(c);
context_read_os_release(c);
context_determine_hostname_source(c);
r = gethostname_strict(&hn);
if (r < 0) {
if (r != -ENXIO)
return log_error_errno(r, "Failed to read local host name: %m");
hn = get_default_hostname();
if (!hn)
return log_oom();
}
dhn = get_default_hostname();
if (!dhn)
return log_oom();
if (isempty(c->data[PROP_ICON_NAME]))
in = context_fallback_icon_name(c);
if (isempty(c->data[PROP_CHASSIS]))
chassis = fallback_chassis();
assert_se(uname(&u) >= 0);
(void) get_hardware_vendor(&vendor);
(void) get_hardware_model(&model);
if (privileged) /* The product UUID is only available to privileged clients */
id128_get_product(&product_uuid);
r = json_build(&v, JSON_BUILD_OBJECT(
JSON_BUILD_PAIR("Hostname", JSON_BUILD_STRING(hn)),
JSON_BUILD_PAIR("StaticHostname", JSON_BUILD_STRING(c->data[PROP_STATIC_HOSTNAME])),
JSON_BUILD_PAIR("PrettyHostname", JSON_BUILD_STRING(c->data[PROP_PRETTY_HOSTNAME])),
JSON_BUILD_PAIR("DefaultHostname", JSON_BUILD_STRING(dhn)),
JSON_BUILD_PAIR("HostnameSource", JSON_BUILD_STRING(hostname_source_to_string(c->hostname_source))),
JSON_BUILD_PAIR("IconName", JSON_BUILD_STRING(in ?: c->data[PROP_ICON_NAME])),
JSON_BUILD_PAIR("Chassis", JSON_BUILD_STRING(chassis ?: c->data[PROP_CHASSIS])),
JSON_BUILD_PAIR("Deployment", JSON_BUILD_STRING(c->data[PROP_DEPLOYMENT])),
JSON_BUILD_PAIR("Location", JSON_BUILD_STRING(c->data[PROP_LOCATION])),
JSON_BUILD_PAIR("KernelName", JSON_BUILD_STRING(u.sysname)),
JSON_BUILD_PAIR("KernelRelease", JSON_BUILD_STRING(u.release)),
JSON_BUILD_PAIR("KernelVersion", JSON_BUILD_STRING(u.version)),
JSON_BUILD_PAIR("OperatingSystemPrettyName", JSON_BUILD_STRING(c->data[PROP_OS_PRETTY_NAME])),
JSON_BUILD_PAIR("OperatingSystemCPEName", JSON_BUILD_STRING(c->data[PROP_OS_CPE_NAME])),
JSON_BUILD_PAIR("OperatingSystemHomeURL", JSON_BUILD_STRING(c->data[PROP_OS_HOME_URL])),
JSON_BUILD_PAIR("HardwareVendor", JSON_BUILD_STRING(vendor)),
JSON_BUILD_PAIR("HardwareModel", JSON_BUILD_STRING(model)),
JSON_BUILD_PAIR_CONDITION(!sd_id128_is_null(product_uuid), "ProductUUID", JSON_BUILD_ID128(product_uuid)),
JSON_BUILD_PAIR_CONDITION(sd_id128_is_null(product_uuid), "ProductUUID", JSON_BUILD_NULL)));
if (r < 0)
return log_error_errno(r, "Failed to build JSON data: %m");
r = json_variant_format(v, 0, &text);
if (r < 0)
return log_error_errno(r, "Failed to format JSON data: %m");
r = sd_bus_message_new_method_return(m, &reply);
if (r < 0)
return r;
r = sd_bus_message_append(reply, "s", text);
if (r < 0) if (r < 0)
return r; return r;
@ -1181,11 +1059,6 @@ static const sd_bus_vtable hostname_vtable[] = {
SD_BUS_PARAM(uuid), SD_BUS_PARAM(uuid),
method_get_product_uuid, method_get_product_uuid,
SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_ARGS("Describe",
SD_BUS_NO_ARGS,
SD_BUS_RESULT("s", json),
method_describe,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END, SD_BUS_VTABLE_END,
}; };

View File

@ -210,25 +210,3 @@ sd_id128_t id128_make_v4_uuid(sd_id128_t id) {
} }
DEFINE_HASH_OPS(id128_hash_ops, sd_id128_t, id128_hash_func, id128_compare_func); DEFINE_HASH_OPS(id128_hash_ops, sd_id128_t, id128_hash_func, id128_compare_func);
int id128_get_product(sd_id128_t *ret) {
sd_id128_t uuid;
int r;
assert(ret);
/* Reads the systems product UUID from DMI or devicetree (where it is located on POWER). This is
* particularly relevant in VM environments, where VM managers typically place a VM uuid there. */
r = id128_read("/sys/class/dmi/id/product_uuid", ID128_UUID, &uuid);
if (r == -ENOENT)
r = id128_read("/sys/firmware/devicetree/base/vm,uuid", ID128_UUID, &uuid);
if (r < 0)
return r;
if (sd_id128_is_null(uuid) || sd_id128_is_allf(uuid))
return -EADDRNOTAVAIL; /* Recognizable error */
*ret = uuid;
return 0;
}

View File

@ -36,5 +36,3 @@ int id128_compare_func(const sd_id128_t *a, const sd_id128_t *b) _pure_;
extern const struct hash_ops id128_hash_ops; extern const struct hash_ops id128_hash_ops;
sd_id128_t id128_make_v4_uuid(sd_id128_t id); sd_id128_t id128_make_v4_uuid(sd_id128_t id);
int id128_get_product(sd_id128_t *ret);

View File

@ -1274,9 +1274,7 @@ static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
if (link->network->dhcp_send_release) { if (link->network->dhcp_send_release) {
r = sd_dhcp_client_send_release(client); r = sd_dhcp_client_send_release(client);
if (r < 0) if (r < 0)
log_link_full_errno(link, log_link_warning_errno(link, r, "Failed to send DHCP RELEASE, ignoring: %m");
ERRNO_IS_DISCONNECT(r) ? LOG_DEBUG : LOG_WARNING,
r, "Failed to send DHCP RELEASE, ignoring: %m");
} }
r = dhcp_lease_lost(link); r = dhcp_lease_lost(link);

View File

@ -2967,3 +2967,15 @@ static const char* const link_state_table[_LINK_STATE_MAX] = {
}; };
DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState); DEFINE_STRING_TABLE_LOOKUP(link_state, LinkState);
int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg) {
const char *err_msg = NULL;
(void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg);
return log_link_full_errno(link, level, err,
"%s: %s%s%s%m",
msg,
strempty(err_msg),
err_msg && !endswith(err_msg, ".") ? "." : "",
err_msg ? " " : "");
}

View File

@ -237,3 +237,10 @@ int link_reconfigure(Link *link, bool force);
int manager_udev_process_link(sd_device_monitor *monitor, sd_device *device, void *userdata); int manager_udev_process_link(sd_device_monitor *monitor, sd_device *device, void *userdata);
int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, Manager *m); int manager_rtnl_process_link(sd_netlink *rtnl, sd_netlink_message *message, Manager *m);
int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg);
#define log_link_message_error_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_ERR, err, msg)
#define log_link_message_warning_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_WARNING, err, msg)
#define log_link_message_notice_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_NOTICE, err, msg)
#define log_link_message_info_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_INFO, err, msg)
#define log_link_message_debug_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_DEBUG, err, msg)

View File

@ -87,8 +87,8 @@ struct Manager {
usec_t speed_meter_usec_new; usec_t speed_meter_usec_new;
usec_t speed_meter_usec_old; usec_t speed_meter_usec_old;
bool dhcp4_prefix_root_cannot_set_table; bool dhcp4_prefix_root_cannot_set_table:1;
bool bridge_mdb_on_master_not_supported; bool bridge_mdb_on_master_not_supported:1;
FirewallContext *fw_ctx; FirewallContext *fw_ctx;
}; };

View File

@ -645,7 +645,7 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
/* link may be NULL */ /* link may be NULL */
if (in_addr_is_set(route->gw_family, &route->gw) && route->nexthop_id == 0) { if (in_addr_is_set(route->gw_family, &route->gw)) {
if (route->gw_family == route->family) { if (route->gw_family == route->family) {
r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->gw_family, &route->gw); r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->gw_family, &route->gw);
if (r < 0) if (r < 0)
@ -717,6 +717,10 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
} }
} }
r = sd_rtnl_message_route_set_type(req, route->type);
if (r < 0)
return log_link_error_errno(link, r, "Could not set route type: %m");
if (!route_type_is_reject(route) && route->nexthop_id == 0) { if (!route_type_is_reject(route) && route->nexthop_id == 0) {
assert(link); /* Those routes must be attached to a specific link */ assert(link); /* Those routes must be attached to a specific link */
@ -765,7 +769,6 @@ int route_remove(
link_netlink_message_handler_t callback) { link_netlink_message_handler_t callback) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
unsigned char type;
int r; int r;
assert(link || manager); assert(link || manager);
@ -783,21 +786,6 @@ int route_remove(
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not create RTM_DELROUTE message: %m"); return log_link_error_errno(link, r, "Could not create RTM_DELROUTE message: %m");
if (route->family == AF_INET && route->nexthop_id > 0 && route->type == RTN_BLACKHOLE)
/* When IPv4 route has nexthop id and the nexthop type is blackhole, even though kernel
* sends RTM_NEWROUTE netlink message with blackhole type, kernel's internal route type
* fib_rt_info::type may not be blackhole. Thus, we cannot know the internal value.
* Moreover, on route removal, the matching is done with the hidden value if we set
* non-zero type in RTM_DELROUTE message. Note, sd_rtnl_message_new_route() sets
* RTN_UNICAST by default. So, we need to clear the type here. */
type = RTN_UNSPEC;
else
type = route->type;
r = sd_rtnl_message_route_set_type(req, type);
if (r < 0)
return log_link_error_errno(link, r, "Could not set route type: %m");
r = route_set_netlink_message(route, req, link); r = route_set_netlink_message(route, req, link);
if (r < 0) if (r < 0)
return r; return r;
@ -854,9 +842,6 @@ static int manager_drop_routes_internal(Manager *manager, bool foreign, const Li
routes = foreign ? manager->routes_foreign : manager->routes; routes = foreign ? manager->routes_foreign : manager->routes;
SET_FOREACH(route, routes) { SET_FOREACH(route, routes) {
if (route->removing)
continue;
/* Do not touch routes managed by the kernel. */ /* Do not touch routes managed by the kernel. */
if (route->protocol == RTPROT_KERNEL) if (route->protocol == RTPROT_KERNEL)
continue; continue;
@ -870,8 +855,6 @@ static int manager_drop_routes_internal(Manager *manager, bool foreign, const Li
k = route_remove(route, manager, NULL, NULL); k = route_remove(route, manager, NULL, NULL);
if (k < 0 && r >= 0) if (k < 0 && r >= 0)
r = k; r = k;
route->removing = true;
} }
return r; return r;
@ -1100,8 +1083,8 @@ int route_configure(
Route **ret) { Route **ret) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
int r, k = 0;
Route *nr; Route *nr;
int r, k;
assert(link); assert(link);
assert(link->manager); assert(link->manager);
@ -1123,10 +1106,6 @@ int route_configure(
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not create RTM_NEWROUTE message: %m"); return log_link_error_errno(link, r, "Could not create RTM_NEWROUTE message: %m");
r = sd_rtnl_message_route_set_type(req, route->type);
if (r < 0)
return log_link_error_errno(link, r, "Could not set route type: %m");
r = route_set_netlink_message(route, req, link); r = route_set_netlink_message(route, req, link);
if (r < 0) if (r < 0)
return r; return r;
@ -1188,22 +1167,19 @@ int route_configure(
if (r < 0) if (r < 0)
return log_link_error_errno(link, r, "Could not append RTA_METRICS attribute: %m"); return log_link_error_errno(link, r, "Could not append RTA_METRICS attribute: %m");
if (route->nexthop_id != 0 || r = append_nexthops(route, req);
in_addr_is_set(route->gw_family, &route->gw) || if (r < 0)
ordered_set_isempty(route->multipath_routes)) { return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m");
if (ordered_set_isempty(route->multipath_routes)) {
k = route_add_and_setup_timer(link, route, NULL, &nr); k = route_add_and_setup_timer(link, route, NULL, &nr);
if (k < 0) if (k < 0)
return k; return k;
} else { } else {
MultipathRoute *m; MultipathRoute *m;
r = append_nexthops(route, req);
if (r < 0)
return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m");
assert(!ret); assert(!ret);
k = 0;
ORDERED_SET_FOREACH(m, route->multipath_routes) { ORDERED_SET_FOREACH(m, route->multipath_routes) {
r = route_add_and_setup_timer(link, route, m, NULL); r = route_add_and_setup_timer(link, route, m, NULL);
if (r < 0) if (r < 0)
@ -2769,17 +2745,8 @@ static int route_section_verify(Route *route, Network *network) {
route->section->filename, route->section->line); route->section->filename, route->section->line);
} }
if ((route->gateway_from_dhcp_or_ra ||
in_addr_is_set(route->gw_family, &route->gw)) &&
!ordered_set_isempty(route->multipath_routes))
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: Gateway= cannot be specified with MultiPathRoute=. "
"Ignoring [Route] section from line %u.",
route->section->filename, route->section->line);
if (route->nexthop_id > 0 && if (route->nexthop_id > 0 &&
(route->gateway_from_dhcp_or_ra || (in_addr_is_set(route->gw_family, &route->gw) ||
in_addr_is_set(route->gw_family, &route->gw) ||
!ordered_set_isempty(route->multipath_routes))) !ordered_set_isempty(route->multipath_routes)))
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: NextHopId= cannot be specified with Gateway= or MultiPathRoute=. " "%s: NextHopId= cannot be specified with Gateway= or MultiPathRoute=. "

View File

@ -52,7 +52,6 @@ typedef struct Route {
bool protocol_set:1; bool protocol_set:1;
bool pref_set:1; bool pref_set:1;
bool gateway_from_dhcp_or_ra:1; bool gateway_from_dhcp_or_ra:1;
bool removing:1;
union in_addr_union gw; union in_addr_union gw;
union in_addr_union dst; union in_addr_union dst;

View File

@ -2,7 +2,6 @@
#include "condition.h" #include "condition.h"
#include "conf-parser.h" #include "conf-parser.h"
#include "networkd-link.h"
#include "networkd-util.h" #include "networkd-util.h"
#include "parse-util.h" #include "parse-util.h"
#include "string-table.h" #include "string-table.h"
@ -224,17 +223,3 @@ unsigned hashmap_find_free_section_line(Hashmap *hashmap) {
return n + 1; return n + 1;
} }
int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg) {
const char *err_msg = NULL;
/* link may be NULL. */
(void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg);
return log_link_full_errno(link, level, err,
"%s: %s%s%s%m",
msg,
strempty(err_msg),
err_msg && !endswith(err_msg, ".") ? "." : "",
err_msg ? " " : "");
}

View File

@ -11,8 +11,6 @@
#include "network-util.h" #include "network-util.h"
#include "string-util.h" #include "string-util.h"
typedef struct Link Link;
typedef struct NetworkConfigSection { typedef struct NetworkConfigSection {
unsigned line; unsigned line;
bool invalid; bool invalid;
@ -75,15 +73,9 @@ static inline bool section_is_invalid(NetworkConfigSection *section) {
DEFINE_TRIVIAL_CLEANUP_FUNC(type*, free_func); \ DEFINE_TRIVIAL_CLEANUP_FUNC(type*, free_func); \
DEFINE_TRIVIAL_CLEANUP_FUNC(type*, free_func##_or_set_invalid); DEFINE_TRIVIAL_CLEANUP_FUNC(type*, free_func##_or_set_invalid);
int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg); static inline int log_message_warning_errno(sd_netlink_message *m, int err, const char *msg) {
#define log_link_message_error_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_ERR, err, msg) const char *err_msg = NULL;
#define log_link_message_warning_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_WARNING, err, msg)
#define log_link_message_notice_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_NOTICE, err, msg) (void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg);
#define log_link_message_info_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_INFO, err, msg) return log_warning_errno(err, "%s: %s%s%m", msg, strempty(err_msg), err_msg ? " " : "");
#define log_link_message_debug_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_DEBUG, err, msg) }
#define log_message_full_errno(m, level, err, msg) log_link_message_full_errno(NULL, m, level, err, msg)
#define log_message_error_errno(m, err, msg) log_message_full_errno(m, LOG_ERR, err, msg)
#define log_message_warning_errno(m, err, msg) log_message_full_errno(m, LOG_WARNING, err, msg)
#define log_message_notice_errno(m, err, msg) log_message_full_errno(m, LOG_NOTICE, err, msg)
#define log_message_info_errno(m, err, msg) log_message_full_errno(m, LOG_INFO, err, msg)
#define log_message_debug_errno(m, err, msg) log_message_full_errno(m, LOG_DEBUG, err, msg)

View File

@ -62,10 +62,16 @@ static int generate_machine_id(const char *root, sd_id128_t *ret) {
} else if (detect_vm() == VIRTUALIZATION_KVM) { } else if (detect_vm() == VIRTUALIZATION_KVM) {
/* If we are not running in a container, see if we are running in qemu/kvm and a /* If we are not running in a container, see if we are
* machine ID was passed in via -uuid on the qemu/kvm command line */ * running in qemu/kvm and a machine ID was passed in
* via -uuid on the qemu/kvm command line */
if (id128_get_product(ret) >= 0) { if (id128_read("/sys/class/dmi/id/product_uuid", ID128_UUID, ret) >= 0) {
log_info("Initializing machine ID from KVM UUID.");
return 0;
}
/* on POWER, it's exported here instead */
if (id128_read("/sys/firmware/devicetree/base/vm,uuid", ID128_UUID, ret) >= 0) {
log_info("Initializing machine ID from KVM UUID."); log_info("Initializing machine ID from KVM UUID.");
return 0; return 0;
} }

View File

@ -33,7 +33,6 @@ typedef enum NamingSchemeFlags {
NAMING_NSPAWN_LONG_HASH = 1 << 8, /* Shorten nspawn interfaces by including 24bit hash, instead of simple truncation */ NAMING_NSPAWN_LONG_HASH = 1 << 8, /* Shorten nspawn interfaces by including 24bit hash, instead of simple truncation */
NAMING_BRIDGE_NO_SLOT = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */ NAMING_BRIDGE_NO_SLOT = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */
NAMING_SLOT_FUNCTION_ID = 1 << 10, /* Use function_id if present to identify PCI hotplug slots */ NAMING_SLOT_FUNCTION_ID = 1 << 10, /* Use function_id if present to identify PCI hotplug slots */
NAMING_16BIT_INDEX = 1 << 11, /* Allow full 16-bit for the onboard index */
/* And now the masks that combine the features above */ /* And now the masks that combine the features above */
NAMING_V238 = 0, NAMING_V238 = 0,
@ -43,7 +42,7 @@ typedef enum NamingSchemeFlags {
NAMING_V243 = NAMING_V241 | NAMING_NETDEVSIM | NAMING_LABEL_NOPREFIX, NAMING_V243 = NAMING_V241 | NAMING_NETDEVSIM | NAMING_LABEL_NOPREFIX,
NAMING_V245 = NAMING_V243 | NAMING_NSPAWN_LONG_HASH, NAMING_V245 = NAMING_V243 | NAMING_NSPAWN_LONG_HASH,
NAMING_V247 = NAMING_V245 | NAMING_BRIDGE_NO_SLOT, NAMING_V247 = NAMING_V245 | NAMING_BRIDGE_NO_SLOT,
NAMING_V249 = NAMING_V247 | NAMING_SLOT_FUNCTION_ID | NAMING_16BIT_INDEX, NAMING_V249 = NAMING_V247 | NAMING_SLOT_FUNCTION_ID,
_NAMING_SCHEME_FLAGS_INVALID = -EINVAL, _NAMING_SCHEME_FLAGS_INVALID = -EINVAL,
} NamingSchemeFlags; } NamingSchemeFlags;

View File

@ -37,8 +37,7 @@
#include "strxcpyx.h" #include "strxcpyx.h"
#include "udev-builtin.h" #include "udev-builtin.h"
#define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1) #define ONBOARD_INDEX_MAX (16*1024-1)
#define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1)
enum netname_type{ enum netname_type{
NET_UNDEF, NET_UNDEF,
@ -163,16 +162,6 @@ static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn
return 0; return 0;
} }
static bool is_valid_onboard_index(unsigned long idx) {
/* Some BIOSes report rubbish indexes that are excessively high (2^24-1 is an index VMware likes to
* report for example). Let's define a cut-off where we don't consider the index reliable anymore. We
* pick some arbitrary cut-off, which is somewhere beyond the realistic number of physical network
* interface a system might have. Ideally the kernel would already filter this crap for us, but it
* doesn't currently. The initial cut-off value (2^14-1) was too conservative for s390 PCI which
* allows for index values up 2^16-1 which is now enabled with the NAMING_16BIT_INDEX naming flag. */
return idx <= (naming_scheme_has(NAMING_16BIT_INDEX) ? ONBOARD_16BIT_INDEX_MAX : ONBOARD_14BIT_INDEX_MAX);
}
/* retrieve on-board index number and label from firmware */ /* retrieve on-board index number and label from firmware */
static int dev_pci_onboard(sd_device *dev, struct netnames *names) { static int dev_pci_onboard(sd_device *dev, struct netnames *names) {
unsigned long idx, dev_port = 0; unsigned long idx, dev_port = 0;
@ -195,7 +184,12 @@ static int dev_pci_onboard(sd_device *dev, struct netnames *names) {
if (idx == 0 && !naming_scheme_has(NAMING_ZERO_ACPI_INDEX)) if (idx == 0 && !naming_scheme_has(NAMING_ZERO_ACPI_INDEX))
return -EINVAL; return -EINVAL;
if (!is_valid_onboard_index(idx)) /* Some BIOSes report rubbish indexes that are excessively high (2^24-1 is an index VMware likes to
* report for example). Let's define a cut-off where we don't consider the index reliable anymore. We
* pick some arbitrary cut-off, which is somewhere beyond the realistic number of physical network
* interface a system might have. Ideally the kernel would already filter this crap for us, but it
* doesn't currently. */
if (idx > ONBOARD_INDEX_MAX)
return -ENOENT; return -ENOENT;
/* kernel provided port index for multiple ports on a single PCI function */ /* kernel provided port index for multiple ports on a single PCI function */

View File

@ -11,8 +11,6 @@
Description=Process Core Dump Socket Description=Process Core Dump Socket
Documentation=man:systemd-coredump(8) Documentation=man:systemd-coredump(8)
DefaultDependencies=no DefaultDependencies=no
Before=shutdown.target
Conflicts=shutdown.target
[Socket] [Socket]
ListenSequentialPacket=/run/systemd/coredump ListenSequentialPacket=/run/systemd/coredump