mirror of
https://github.com/systemd/systemd
synced 2026-03-13 16:44:48 +01:00
Compare commits
19 Commits
f813b62316
...
4e947bd049
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4e947bd049 | ||
|
|
c3a5240e3a | ||
|
|
5a7eb46c02 | ||
|
|
34bcc67681 | ||
|
|
97a7243650 | ||
|
|
ac8a4f6b78 | ||
|
|
7ecead8f08 | ||
|
|
f8da67cdf2 | ||
|
|
f2a434a5b8 | ||
|
|
61d44b6beb | ||
|
|
c52e295d68 | ||
|
|
66ee229879 | ||
|
|
b4be4ff8ae | ||
|
|
3c7f1c0757 | ||
|
|
8a9ce525d1 | ||
|
|
c3fa1257da | ||
|
|
fd221544f2 | ||
|
|
e558d4f47a | ||
|
|
4cbd379e01 |
@ -195,6 +195,7 @@
|
||||
|
||||
<xi:include href="standard-options.xml" xpointer="help" />
|
||||
<xi:include href="standard-options.xml" xpointer="version" />
|
||||
<xi:include href="standard-options.xml" xpointer="json" />
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
||||
@ -58,6 +58,7 @@ node /org/freedesktop/hostname1 {
|
||||
in b interactive);
|
||||
GetProductUUID(in b interactive,
|
||||
out ay uuid);
|
||||
Describe(out s UNNAMED);
|
||||
properties:
|
||||
readonly s Hostname = '...';
|
||||
readonly s StaticHostname = '...';
|
||||
@ -118,6 +119,8 @@ node /org/freedesktop/hostname1 {
|
||||
|
||||
<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="StaticHostname"/>
|
||||
@ -232,6 +235,17 @@ node /org/freedesktop/hostname1 {
|
||||
<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>
|
||||
|
||||
<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>
|
||||
<title>Methods</title>
|
||||
|
||||
@ -261,22 +275,12 @@ node /org/freedesktop/hostname1 {
|
||||
<citerefentry><refentrytitle>machine-info</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
|
||||
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
|
||||
requires root privileges, and this method allows access to unprivileged clients through the polkit
|
||||
framework.</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>
|
||||
<para><function>Describe()</function> returns a JSON representation of all properties in one.</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
|
||||
@ -376,7 +376,12 @@
|
||||
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
|
||||
numbers, which could either result in an incorrect value of the <varname>ID_NET_NAME_SLOT</varname>
|
||||
property or none at all.</para></listitem>
|
||||
property or none at all.</para>
|
||||
|
||||
<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>
|
||||
|
||||
</variablelist>
|
||||
|
||||
@ -17,7 +17,9 @@
|
||||
#include "format-table.h"
|
||||
#include "hostname-setup.h"
|
||||
#include "hostname-util.h"
|
||||
#include "json.h"
|
||||
#include "main-func.h"
|
||||
#include "parse-argument.h"
|
||||
#include "pretty-print.h"
|
||||
#include "spawn-polkit-agent.h"
|
||||
#include "terminal-util.h"
|
||||
@ -30,6 +32,7 @@ static char *arg_host = NULL;
|
||||
static bool arg_transient = false;
|
||||
static bool arg_pretty = false;
|
||||
static bool arg_static = false;
|
||||
static JsonFormatFlags arg_json_format_flags = JSON_FORMAT_OFF;
|
||||
|
||||
typedef struct StatusInfo {
|
||||
const char *hostname;
|
||||
@ -317,6 +320,37 @@ static int show_all_names(sd_bus *bus) {
|
||||
|
||||
static int show_status(int argc, char **argv, void *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) {
|
||||
const char *attr;
|
||||
@ -489,6 +523,8 @@ static int help(void) {
|
||||
" --transient Only set transient hostname\n"
|
||||
" --static Only set static hostname\n"
|
||||
" --pretty Only set pretty hostname\n"
|
||||
" --json=pretty|short|off\n"
|
||||
" Generate JSON output\n"
|
||||
"\nSee the %s for details.\n",
|
||||
program_invocation_short_name,
|
||||
ansi_highlight(),
|
||||
@ -509,7 +545,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_NO_ASK_PASSWORD,
|
||||
ARG_TRANSIENT,
|
||||
ARG_STATIC,
|
||||
ARG_PRETTY
|
||||
ARG_PRETTY,
|
||||
ARG_JSON,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@ -521,10 +558,11 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "host", required_argument, NULL, 'H' },
|
||||
{ "machine", required_argument, NULL, 'M' },
|
||||
{ "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
|
||||
{ "json", required_argument, NULL, ARG_JSON },
|
||||
{}
|
||||
};
|
||||
|
||||
int c;
|
||||
int c, r;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
@ -565,6 +603,13 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_ask_password = false;
|
||||
break;
|
||||
|
||||
case ARG_JSON:
|
||||
r = parse_json_argument(optarg, &arg_json_format_flags);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#include "hostname-setup.h"
|
||||
#include "hostname-util.h"
|
||||
#include "id128-util.h"
|
||||
#include "json.h"
|
||||
#include "main-func.h"
|
||||
#include "missing_capability.h"
|
||||
#include "nscd-flush.h"
|
||||
@ -40,6 +41,8 @@
|
||||
|
||||
#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 {
|
||||
/* Read from /etc/hostname */
|
||||
PROP_STATIC_HOSTNAME,
|
||||
@ -51,9 +54,6 @@ enum {
|
||||
PROP_DEPLOYMENT,
|
||||
PROP_LOCATION,
|
||||
|
||||
PROP_HARDWARE_VENDOR,
|
||||
PROP_HARDWARE_MODEL,
|
||||
|
||||
/* Read from /etc/os-release (or /usr/lib/os-release) */
|
||||
PROP_OS_PRETTY_NAME,
|
||||
PROP_OS_CPE_NAME,
|
||||
@ -449,6 +449,41 @@ static int context_write_data_machine_info(Context *c) {
|
||||
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(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
@ -457,20 +492,11 @@ static int property_get_hardware_vendor(
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
||||
const char *hardware_vendor = NULL;
|
||||
int r;
|
||||
|
||||
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);
|
||||
}
|
||||
_cleanup_free_ char *vendor = NULL;
|
||||
|
||||
if (sd_device_get_property_value(device, "ID_VENDOR_FROM_DATABASE", &hardware_vendor) < 0)
|
||||
(void) sd_device_get_property_value(device, "ID_VENDOR", &hardware_vendor);
|
||||
|
||||
return sd_bus_message_append(reply, "s", hardware_vendor);
|
||||
(void) get_hardware_vendor(&vendor);
|
||||
return sd_bus_message_append(reply, "s", vendor);
|
||||
}
|
||||
|
||||
static int property_get_hardware_model(
|
||||
@ -481,20 +507,11 @@ static int property_get_hardware_model(
|
||||
sd_bus_message *reply,
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
||||
const char *hardware_model = NULL;
|
||||
int r;
|
||||
|
||||
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);
|
||||
}
|
||||
_cleanup_free_ char *model = NULL;
|
||||
|
||||
if (sd_device_get_property_value(device, "ID_MODEL_FROM_DATABASE", &hardware_model) < 0)
|
||||
(void) sd_device_get_property_value(device, "ID_MODEL", &hardware_model);
|
||||
|
||||
return sd_bus_message_append(reply, "s", hardware_model);
|
||||
(void) get_hardware_model(&model);
|
||||
return sd_bus_message_append(reply, "s", model);
|
||||
}
|
||||
|
||||
static int property_get_hostname(
|
||||
@ -548,13 +565,46 @@ static int property_get_default_hostname(
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
_cleanup_free_ char *hn = get_default_hostname();
|
||||
_cleanup_free_ char *hn = NULL;
|
||||
|
||||
hn = get_default_hostname();
|
||||
if (!hn)
|
||||
return log_oom();
|
||||
|
||||
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(
|
||||
sd_bus *bus,
|
||||
const char *path,
|
||||
@ -565,36 +615,10 @@ static int property_get_hostname_source(
|
||||
sd_bus_error *error) {
|
||||
|
||||
Context *c = userdata;
|
||||
int r;
|
||||
assert(c);
|
||||
|
||||
context_read_etc_hostname(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;
|
||||
}
|
||||
}
|
||||
context_determine_hostname_source(c);
|
||||
|
||||
return sd_bus_message_append(reply, "s", hostname_source_to_string(c->hostname_source));
|
||||
}
|
||||
@ -932,28 +956,12 @@ 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) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
Context *c = userdata;
|
||||
bool has_uuid = false;
|
||||
int interactive, r;
|
||||
sd_id128_t uuid;
|
||||
|
||||
assert(m);
|
||||
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);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -972,11 +980,125 @@ static int method_get_product_uuid(sd_bus_message *m, void *userdata, sd_bus_err
|
||||
if (r == 0)
|
||||
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);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_bus_message_append_array(reply, 'y', &uuid, sizeof(uuid));
|
||||
r = sd_bus_message_append_array(reply, 'y', uuid.bytes, sizeof(uuid.bytes));
|
||||
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)
|
||||
return r;
|
||||
|
||||
@ -1059,6 +1181,11 @@ static const sd_bus_vtable hostname_vtable[] = {
|
||||
SD_BUS_PARAM(uuid),
|
||||
method_get_product_uuid,
|
||||
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,
|
||||
};
|
||||
|
||||
@ -210,3 +210,25 @@ 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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -36,3 +36,5 @@ int id128_compare_func(const sd_id128_t *a, const sd_id128_t *b) _pure_;
|
||||
extern const struct hash_ops id128_hash_ops;
|
||||
|
||||
sd_id128_t id128_make_v4_uuid(sd_id128_t id);
|
||||
|
||||
int id128_get_product(sd_id128_t *ret);
|
||||
|
||||
@ -1274,7 +1274,9 @@ static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
|
||||
if (link->network->dhcp_send_release) {
|
||||
r = sd_dhcp_client_send_release(client);
|
||||
if (r < 0)
|
||||
log_link_warning_errno(link, r, "Failed to send DHCP RELEASE, ignoring: %m");
|
||||
log_link_full_errno(link,
|
||||
ERRNO_IS_DISCONNECT(r) ? LOG_DEBUG : LOG_WARNING,
|
||||
r, "Failed to send DHCP RELEASE, ignoring: %m");
|
||||
}
|
||||
|
||||
r = dhcp_lease_lost(link);
|
||||
|
||||
@ -2967,15 +2967,3 @@ static const char* const link_state_table[_LINK_STATE_MAX] = {
|
||||
};
|
||||
|
||||
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 ? " " : "");
|
||||
}
|
||||
|
||||
@ -237,10 +237,3 @@ int link_reconfigure(Link *link, bool force);
|
||||
|
||||
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 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)
|
||||
|
||||
@ -87,8 +87,8 @@ struct Manager {
|
||||
usec_t speed_meter_usec_new;
|
||||
usec_t speed_meter_usec_old;
|
||||
|
||||
bool dhcp4_prefix_root_cannot_set_table:1;
|
||||
bool bridge_mdb_on_master_not_supported:1;
|
||||
bool dhcp4_prefix_root_cannot_set_table;
|
||||
bool bridge_mdb_on_master_not_supported;
|
||||
|
||||
FirewallContext *fw_ctx;
|
||||
};
|
||||
|
||||
@ -645,7 +645,7 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
|
||||
|
||||
/* link may be NULL */
|
||||
|
||||
if (in_addr_is_set(route->gw_family, &route->gw)) {
|
||||
if (in_addr_is_set(route->gw_family, &route->gw) && route->nexthop_id == 0) {
|
||||
if (route->gw_family == route->family) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->gw_family, &route->gw);
|
||||
if (r < 0)
|
||||
@ -717,10 +717,6 @@ 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) {
|
||||
assert(link); /* Those routes must be attached to a specific link */
|
||||
|
||||
@ -769,6 +765,7 @@ int route_remove(
|
||||
link_netlink_message_handler_t callback) {
|
||||
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
unsigned char type;
|
||||
int r;
|
||||
|
||||
assert(link || manager);
|
||||
@ -786,6 +783,21 @@ int route_remove(
|
||||
if (r < 0)
|
||||
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);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -842,6 +854,9 @@ static int manager_drop_routes_internal(Manager *manager, bool foreign, const Li
|
||||
|
||||
routes = foreign ? manager->routes_foreign : manager->routes;
|
||||
SET_FOREACH(route, routes) {
|
||||
if (route->removing)
|
||||
continue;
|
||||
|
||||
/* Do not touch routes managed by the kernel. */
|
||||
if (route->protocol == RTPROT_KERNEL)
|
||||
continue;
|
||||
@ -855,6 +870,8 @@ static int manager_drop_routes_internal(Manager *manager, bool foreign, const Li
|
||||
k = route_remove(route, manager, NULL, NULL);
|
||||
if (k < 0 && r >= 0)
|
||||
r = k;
|
||||
|
||||
route->removing = true;
|
||||
}
|
||||
|
||||
return r;
|
||||
@ -1083,8 +1100,8 @@ int route_configure(
|
||||
Route **ret) {
|
||||
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
int r, k = 0;
|
||||
Route *nr;
|
||||
int r, k;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
@ -1106,6 +1123,10 @@ int route_configure(
|
||||
if (r < 0)
|
||||
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);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -1167,19 +1188,22 @@ int route_configure(
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_METRICS attribute: %m");
|
||||
|
||||
r = append_nexthops(route, req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m");
|
||||
|
||||
if (ordered_set_isempty(route->multipath_routes)) {
|
||||
if (route->nexthop_id != 0 ||
|
||||
in_addr_is_set(route->gw_family, &route->gw) ||
|
||||
ordered_set_isempty(route->multipath_routes)) {
|
||||
k = route_add_and_setup_timer(link, route, NULL, &nr);
|
||||
if (k < 0)
|
||||
return k;
|
||||
} else {
|
||||
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);
|
||||
|
||||
k = 0;
|
||||
ORDERED_SET_FOREACH(m, route->multipath_routes) {
|
||||
r = route_add_and_setup_timer(link, route, m, NULL);
|
||||
if (r < 0)
|
||||
@ -2745,8 +2769,17 @@ static int route_section_verify(Route *route, Network *network) {
|
||||
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 &&
|
||||
(in_addr_is_set(route->gw_family, &route->gw) ||
|
||||
(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: NextHopId= cannot be specified with Gateway= or MultiPathRoute=. "
|
||||
|
||||
@ -52,6 +52,7 @@ typedef struct Route {
|
||||
bool protocol_set:1;
|
||||
bool pref_set:1;
|
||||
bool gateway_from_dhcp_or_ra:1;
|
||||
bool removing:1;
|
||||
|
||||
union in_addr_union gw;
|
||||
union in_addr_union dst;
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include "condition.h"
|
||||
#include "conf-parser.h"
|
||||
#include "networkd-link.h"
|
||||
#include "networkd-util.h"
|
||||
#include "parse-util.h"
|
||||
#include "string-table.h"
|
||||
@ -223,3 +224,17 @@ unsigned hashmap_find_free_section_line(Hashmap *hashmap) {
|
||||
|
||||
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 ? " " : "");
|
||||
}
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
#include "network-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
typedef struct Link Link;
|
||||
|
||||
typedef struct NetworkConfigSection {
|
||||
unsigned line;
|
||||
bool invalid;
|
||||
@ -73,9 +75,15 @@ static inline bool section_is_invalid(NetworkConfigSection *section) {
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(type*, free_func); \
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(type*, free_func##_or_set_invalid);
|
||||
|
||||
static inline int log_message_warning_errno(sd_netlink_message *m, int err, const char *msg) {
|
||||
const char *err_msg = NULL;
|
||||
|
||||
(void) sd_netlink_message_read_string(m, NLMSGERR_ATTR_MSG, &err_msg);
|
||||
return log_warning_errno(err, "%s: %s%s%m", msg, strempty(err_msg), err_msg ? " " : "");
|
||||
}
|
||||
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)
|
||||
#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)
|
||||
|
||||
@ -62,16 +62,10 @@ static int generate_machine_id(const char *root, sd_id128_t *ret) {
|
||||
|
||||
} else if (detect_vm() == VIRTUALIZATION_KVM) {
|
||||
|
||||
/* If we are not running in a container, see if we are
|
||||
* running in qemu/kvm and a machine ID was passed in
|
||||
* via -uuid on the qemu/kvm command line */
|
||||
/* If we are not running in a container, see if we are running in qemu/kvm and a
|
||||
* machine ID was passed in via -uuid on the qemu/kvm command line */
|
||||
|
||||
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) {
|
||||
if (id128_get_product(ret) >= 0) {
|
||||
log_info("Initializing machine ID from KVM UUID.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ typedef enum NamingSchemeFlags {
|
||||
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_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 */
|
||||
NAMING_V238 = 0,
|
||||
@ -42,7 +43,7 @@ typedef enum NamingSchemeFlags {
|
||||
NAMING_V243 = NAMING_V241 | NAMING_NETDEVSIM | NAMING_LABEL_NOPREFIX,
|
||||
NAMING_V245 = NAMING_V243 | NAMING_NSPAWN_LONG_HASH,
|
||||
NAMING_V247 = NAMING_V245 | NAMING_BRIDGE_NO_SLOT,
|
||||
NAMING_V249 = NAMING_V247 | NAMING_SLOT_FUNCTION_ID,
|
||||
NAMING_V249 = NAMING_V247 | NAMING_SLOT_FUNCTION_ID | NAMING_16BIT_INDEX,
|
||||
|
||||
_NAMING_SCHEME_FLAGS_INVALID = -EINVAL,
|
||||
} NamingSchemeFlags;
|
||||
|
||||
@ -37,7 +37,8 @@
|
||||
#include "strxcpyx.h"
|
||||
#include "udev-builtin.h"
|
||||
|
||||
#define ONBOARD_INDEX_MAX (16*1024-1)
|
||||
#define ONBOARD_14BIT_INDEX_MAX ((1U << 14) - 1)
|
||||
#define ONBOARD_16BIT_INDEX_MAX ((1U << 16) - 1)
|
||||
|
||||
enum netname_type{
|
||||
NET_UNDEF,
|
||||
@ -162,6 +163,16 @@ static int get_virtfn_info(sd_device *dev, struct netnames *names, struct virtfn
|
||||
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 */
|
||||
static int dev_pci_onboard(sd_device *dev, struct netnames *names) {
|
||||
unsigned long idx, dev_port = 0;
|
||||
@ -184,12 +195,7 @@ static int dev_pci_onboard(sd_device *dev, struct netnames *names) {
|
||||
if (idx == 0 && !naming_scheme_has(NAMING_ZERO_ACPI_INDEX))
|
||||
return -EINVAL;
|
||||
|
||||
/* 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)
|
||||
if (!is_valid_onboard_index(idx))
|
||||
return -ENOENT;
|
||||
|
||||
/* kernel provided port index for multiple ports on a single PCI function */
|
||||
|
||||
@ -11,6 +11,8 @@
|
||||
Description=Process Core Dump Socket
|
||||
Documentation=man:systemd-coredump(8)
|
||||
DefaultDependencies=no
|
||||
Before=shutdown.target
|
||||
Conflicts=shutdown.target
|
||||
|
||||
[Socket]
|
||||
ListenSequentialPacket=/run/systemd/coredump
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user