diff options
32 files changed, 435 insertions, 294 deletions
@@ -321,8 +321,6 @@ Features: - add LLDP client side support - the DHCP lease data (such as NTP/DNS) is still made available when a carrier is lost on a link. It should be removed instantly. - - .network setting that allows overriding of the hostname to send to the dhcp server - http://lists.freedesktop.org/archives/systemd-devel/2014-July/021550.html - expose in the API the following bits: - option 15, domain name and/or option 119, search list - option 12, host name and/or option 81, fqdn diff --git a/configure.ac b/configure.ac index 999f9f84d3..ff6364aba2 100644 --- a/configure.ac +++ b/configure.ac @@ -299,7 +299,8 @@ AC_CHECK_DECLS([IFLA_INET6_ADDR_GEN_MODE, IFLA_BOND_AD_INFO, IFLA_VLAN_PROTOCOL, IFLA_VXLAN_REMCSUM_NOPARTIAL, - IFLA_IPTUN_6RD_RELAY_PREFIXLEN, + IFLA_IPTUN_ENCAP_DPORT, + IFLA_GRE_ENCAP_DPORT, IFLA_BRIDGE_VLAN_INFO, IFLA_BRPORT_UNICAST_FLOOD, NDA_IFINDEX, diff --git a/hwdb/70-mouse.hwdb b/hwdb/70-mouse.hwdb index 1633321502..bc4b597bbf 100644 --- a/hwdb/70-mouse.hwdb +++ b/hwdb/70-mouse.hwdb @@ -247,6 +247,10 @@ mouse:usb:v046dpc05a:name:Logitech USB Optical Mouse: mouse:usb:v046dpc065:name:Logitech USB Laser Mouse: MOUSE_DPI=1000@125 +# Logitech MX Master +mouse:usb:v046dp4041:name:Logitech MX Master: + MOUSE_DPI=1000@166 + # Logitech MK260 Wireless Combo Receiver aka M-R0011 mouse:usb:v046dpc52e:name:Logitech USB Receiver: MOUSE_DPI=1000@200 diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index ff7b85453f..d15c21be60 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -491,6 +491,19 @@ </listitem> </varlistentry> <varlistentry> + <term><varname>IPv6FlowLabel=</varname></term> + <listitem> + <para>Configures The 20-bit Flow Label (see <ulink url="https://tools.ietf.org/html/rfc6437"> + RFC 6437</ulink>) field in the IPv6 header (see <ulink url="https://tools.ietf.org/html/rfc2460"> + RFC 2460</ulink>), is used by a node to label packets of a flow. + It's only used for IPv6 Tunnels. + A Flow Label of zero is used to indicate packets that have + not been labeled. Takes following values. + When <literal>inherit</literal> it uses the original flowlabel, + or can be configured to any value betwen 0 to 0xFFFFF.</para> + </listitem> + </varlistentry> + <varlistentry> <term><varname>Mode=</varname></term> <listitem> <para>An <literal>ip6tnl</literal> tunnels can have three diff --git a/man/systemd.network.xml b/man/systemd.network.xml index ff01da6249..90a0e8fff6 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -589,6 +589,12 @@ </listitem> </varlistentry> <varlistentry> + <term><varname>Hostname=</varname></term> + <listitem> + <para>Hostname is a option to override the machine's hostname that will be sent to the DHCP server</para> + </listitem> + </varlistentry> + <varlistentry> <term><varname>UseDomains=</varname></term> <listitem> <para>When true (not the default), the domain name diff --git a/src/basic/macro.h b/src/basic/macro.h index 5fa17ed208..ea01d701d2 100644 --- a/src/basic/macro.h +++ b/src/basic/macro.h @@ -406,12 +406,12 @@ do { \ #define IN_SET(x, y, ...) \ ({ \ - const typeof(y) _y = (y); \ - const typeof(_y) _x = (x); \ + static const typeof(y) _array[] = { (y), __VA_ARGS__ }; \ + const typeof(y) _x = (x); \ unsigned _i; \ bool _found = false; \ - for (_i = 0; _i < 1 + sizeof((const typeof(_x)[]) { __VA_ARGS__ })/sizeof(const typeof(_x)); _i++) \ - if (((const typeof(_x)[]) { _y, __VA_ARGS__ })[_i] == _x) { \ + for (_i = 0; _i < ELEMENTSOF(_array); _i++) \ + if (_array[_i] == _x) { \ _found = true; \ break; \ } \ diff --git a/src/basic/missing.h b/src/basic/missing.h index be7f6186fc..bd49f10e76 100644 --- a/src/basic/missing.h +++ b/src/basic/missing.h @@ -772,7 +772,7 @@ static inline int setns(int fd, int nstype) { #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1) #endif -#if !HAVE_DECL_IFLA_IPTUN_6RD_RELAY_PREFIXLEN +#if !HAVE_DECL_IFLA_IPTUN_ENCAP_DPORT #define IFLA_IPTUN_UNSPEC 0 #define IFLA_IPTUN_LINK 1 #define IFLA_IPTUN_LOCAL 2 @@ -788,11 +788,41 @@ static inline int setns(int fd, int nstype) { #define IFLA_IPTUN_6RD_RELAY_PREFIX 12 #define IFLA_IPTUN_6RD_PREFIXLEN 13 #define IFLA_IPTUN_6RD_RELAY_PREFIXLEN 14 -#define __IFLA_IPTUN_MAX 15 +#define IFLA_IPTUN_ENCAP_TYPE 15 +#define IFLA_IPTUN_ENCAP_FLAGS 16 +#define IFLA_IPTUN_ENCAP_SPORT 17 +#define IFLA_IPTUN_ENCAP_DPORT 18 + +#define __IFLA_IPTUN_MAX 19 #define IFLA_IPTUN_MAX (__IFLA_IPTUN_MAX - 1) #endif +#if !HAVE_DECL_IFLA_GRE_ENCAP_DPORT +#define IFLA_GRE_UNSPEC 0 +#define IFLA_GRE_LINK 1 +#define IFLA_GRE_IFLAGS 2 +#define IFLA_GRE_OFLAGS 3 +#define IFLA_GRE_IKEY 4 +#define IFLA_GRE_OKEY 5 +#define IFLA_GRE_LOCAL 6 +#define IFLA_GRE_REMOTE 7 +#define IFLA_GRE_TTL 8 +#define IFLA_GRE_TOS 9 +#define IFLA_GRE_PMTUDISC 10 +#define IFLA_GRE_ENCAP_LIMIT 11 +#define IFLA_GRE_FLOWINFO 12 +#define IFLA_GRE_FLAGS 13 +#define IFLA_GRE_ENCAP_TYPE 14 +#define IFLA_GRE_ENCAP_FLAGS 15 +#define IFLA_GRE_ENCAP_SPORT 16 +#define IFLA_GRE_ENCAP_DPORT 17 + +#define __IFLA_GRE_MAX 18 + +#define IFLA_GRE_MAX (__IFLA_GRE_MAX - 1) +#endif + #if !HAVE_DECL_IFLA_BRIDGE_VLAN_INFO #define IFLA_BRIDGE_FLAGS 0 #define IFLA_BRIDGE_MODE 1 diff --git a/src/bootchart/bootchart.c b/src/bootchart/bootchart.c index 3360bc85be..1625d51fa8 100644 --- a/src/bootchart/bootchart.c +++ b/src/bootchart/bootchart.c @@ -387,9 +387,6 @@ int main(int argc, char *argv[]) { for (samples = 0; !exiting && samples < arg_samples_len; samples++) { int res; double sample_stop; - struct timespec req; - time_t newint_s; - long newint_ns; double elapsed; double timeleft; @@ -427,18 +424,17 @@ int main(int argc, char *argv[]) { elapsed = (sample_stop - sampledata->sampletime) * 1000000000.0; timeleft = interval - elapsed; - newint_s = (time_t)(timeleft / 1000000000.0); - newint_ns = (long)(timeleft - (newint_s * 1000000000.0)); - /* * check if we have not consumed our entire timeslice. If we * do, don't sleep and take a new sample right away. * we'll lose all the missed samples and overrun our total * time */ - if (newint_ns > 0 || newint_s > 0) { - req.tv_sec = newint_s; - req.tv_nsec = newint_ns; + if (timeleft > 0) { + struct timespec req; + + req.tv_sec = (time_t)(timeleft / 1000000000.0); + req.tv_nsec = (long)(timeleft - (req.tv_sec * 1000000000.0)); res = nanosleep(&req, NULL); if (res) { @@ -452,7 +448,7 @@ int main(int argc, char *argv[]) { } else { overrun++; /* calculate how many samples we lost and scrap them */ - arg_samples_len -= (int)(newint_ns / interval); + arg_samples_len -= (int)(-timeleft / interval); } LIST_PREPEND(link, head, sampledata); } diff --git a/src/core/automount.c b/src/core/automount.c index d847dc1629..90b331f70e 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -1066,7 +1066,6 @@ const UnitVTable automount_vtable = { .finished_start_job = { [JOB_DONE] = "Set up automount %s.", [JOB_FAILED] = "Failed to set up automount %s.", - [JOB_DEPENDENCY] = "Dependency failed for %s.", }, .finished_stop_job = { [JOB_DONE] = "Unset automount %s.", diff --git a/src/core/busname.c b/src/core/busname.c index 2085721546..9530a87311 100644 --- a/src/core/busname.c +++ b/src/core/busname.c @@ -1065,13 +1065,10 @@ const UnitVTable busname_vtable = { .finished_start_job = { [JOB_DONE] = "Listening on %s.", [JOB_FAILED] = "Failed to listen on %s.", - [JOB_DEPENDENCY] = "Dependency failed for %s.", - [JOB_TIMEOUT] = "Timed out starting %s.", }, .finished_stop_job = { [JOB_DONE] = "Closed %s.", [JOB_FAILED] = "Failed stopping %s.", - [JOB_TIMEOUT] = "Timed out stopping %s.", }, }, }; diff --git a/src/core/job.c b/src/core/job.c index 1448e5b69a..15f5cc0cc9 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -495,10 +495,48 @@ static void job_change_type(Job *j, JobType newtype) { j->type = newtype; } +static int job_perform_on_unit(Job **j) { + /* While we execute this operation the job might go away (for + * example: because it finishes immediately or is replaced by a new, + * conflicting job.) To make sure we don't access a freed job later on + * we store the id here, so that we can verify the job is still + * valid. */ + Manager *m = (*j)->manager; + Unit *u = (*j)->unit; + JobType t = (*j)->type; + uint32_t id = (*j)->id; + int r; + + switch (t) { + case JOB_START: + r = unit_start(u); + break; + + case JOB_RESTART: + t = JOB_STOP; + case JOB_STOP: + r = unit_stop(u); + break; + + case JOB_RELOAD: + r = unit_reload(u); + break; + + default: + assert_not_reached("Invalid job type"); + } + + /* Log if the job still exists and the start/stop/reload function + * actually did something. */ + *j = manager_get_job(m, id); + if (*j && r > 0) + unit_status_emit_starting_stopping_reloading(u, t); + + return r; +} + int job_run_and_invalidate(Job *j) { int r; - uint32_t id; - Manager *m = j->manager; assert(j); assert(j->installed); @@ -517,23 +555,9 @@ int job_run_and_invalidate(Job *j) { job_set_state(j, JOB_RUNNING); job_add_to_dbus_queue(j); - /* While we execute this operation the job might go away (for - * example: because it is replaced by a new, conflicting - * job.) To make sure we don't access a freed job later on we - * store the id here, so that we can verify the job is still - * valid. */ - id = j->id; switch (j->type) { - case JOB_START: - r = unit_start(j->unit); - - /* If this unit cannot be started, then simply wait */ - if (r == -EBADR) - r = 0; - break; - case JOB_VERIFY_ACTIVE: { UnitActiveState t = unit_active_state(j->unit); if (UNIT_IS_ACTIVE_OR_RELOADING(t)) @@ -545,17 +569,19 @@ int job_run_and_invalidate(Job *j) { break; } + case JOB_START: case JOB_STOP: case JOB_RESTART: - r = unit_stop(j->unit); + r = job_perform_on_unit(&j); - /* If this unit cannot stopped, then simply wait. */ + /* If the unit type does not support starting/stopping, + * then simply wait. */ if (r == -EBADR) r = 0; break; case JOB_RELOAD: - r = unit_reload(j->unit); + r = job_perform_on_unit(&j); break; case JOB_NOP: @@ -566,7 +592,6 @@ int job_run_and_invalidate(Job *j) { assert_not_reached("Unknown job type"); } - j = manager_get_job(m, id); if (j) { if (r == -EALREADY) r = job_finish_and_invalidate(j, JOB_DONE, true); @@ -588,161 +613,110 @@ int job_run_and_invalidate(Job *j) { } _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) { + const char *format; const UnitStatusMessageFormats *format_table; + static const char *const generic_finished_start_job[_JOB_RESULT_MAX] = { + [JOB_DONE] = "Started %s.", + [JOB_TIMEOUT] = "Timed out starting %s.", + [JOB_FAILED] = "Failed to start %s.", + [JOB_DEPENDENCY] = "Dependency failed for %s.", + [JOB_ASSERT] = "Assertion failed for %s.", + [JOB_UNSUPPORTED] = "Starting of %s not supported.", + }; + static const char *const generic_finished_stop_job[_JOB_RESULT_MAX] = { + [JOB_DONE] = "Stopped %s.", + [JOB_FAILED] = "Stopped (with error) %s.", + [JOB_TIMEOUT] = "Timed out stoppping %s.", + }; + static const char *const generic_finished_reload_job[_JOB_RESULT_MAX] = { + [JOB_DONE] = "Reloaded %s.", + [JOB_FAILED] = "Reload failed for %s.", + [JOB_TIMEOUT] = "Timed out reloading %s.", + }; + /* When verify-active detects the unit is inactive, report it. + * Most likely a DEPEND warning from a requisiting unit will + * occur next and it's nice to see what was requisited. */ + static const char *const generic_finished_verify_active_job[_JOB_RESULT_MAX] = { + [JOB_SKIPPED] = "%s is not active.", + }; assert(u); assert(t >= 0); assert(t < _JOB_TYPE_MAX); - format_table = &UNIT_VTABLE(u)->status_message_formats; - if (!format_table) - return NULL; + if (t == JOB_START || t == JOB_STOP || t == JOB_RESTART) { + format_table = &UNIT_VTABLE(u)->status_message_formats; + if (format_table) { + format = t == JOB_START ? format_table->finished_start_job[result] : + format_table->finished_stop_job[result]; + if (format) + return format; + } + } + /* Return generic strings */ if (t == JOB_START) - return format_table->finished_start_job[result]; + return generic_finished_start_job[result]; else if (t == JOB_STOP || t == JOB_RESTART) - return format_table->finished_stop_job[result]; + return generic_finished_stop_job[result]; + else if (t == JOB_RELOAD) + return generic_finished_reload_job[result]; + else if (t == JOB_VERIFY_ACTIVE) + return generic_finished_verify_active_job[result]; return NULL; } -_pure_ static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) { +static void job_print_status_message(Unit *u, JobType t, JobResult result) { const char *format; + static const char* const job_result_status_table[_JOB_RESULT_MAX] = { + [JOB_DONE] = ANSI_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, + [JOB_TIMEOUT] = ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, + [JOB_FAILED] = ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, + [JOB_DEPENDENCY] = ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, + [JOB_SKIPPED] = ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, + [JOB_ASSERT] = ANSI_HIGHLIGHT_YELLOW_ON "ASSERT" ANSI_HIGHLIGHT_OFF, + [JOB_UNSUPPORTED] = ANSI_HIGHLIGHT_YELLOW_ON "UNSUPP" ANSI_HIGHLIGHT_OFF, + }; assert(u); assert(t >= 0); assert(t < _JOB_TYPE_MAX); format = job_get_status_message_format(u, t, result); - if (format) - return format; - - /* Return generic strings */ - if (t == JOB_START) { - if (result == JOB_DONE) - return "Started %s."; - else if (result == JOB_TIMEOUT) - return "Timed out starting %s."; - else if (result == JOB_FAILED) - return "Failed to start %s."; - else if (result == JOB_DEPENDENCY) - return "Dependency failed for %s."; - else if (result == JOB_ASSERT) - return "Assertion failed for %s."; - else if (result == JOB_UNSUPPORTED) - return "Starting of %s not supported."; - } else if (t == JOB_STOP || t == JOB_RESTART) { - if (result == JOB_DONE) - return "Stopped %s."; - else if (result == JOB_FAILED) - return "Stopped (with error) %s."; - else if (result == JOB_TIMEOUT) - return "Timed out stoppping %s."; - } else if (t == JOB_RELOAD) { - if (result == JOB_DONE) - return "Reloaded %s."; - else if (result == JOB_FAILED) - return "Reload failed for %s."; - else if (result == JOB_TIMEOUT) - return "Timed out reloading %s."; - } - - return NULL; -} + if (!format) + return; -static void job_print_status_message(Unit *u, JobType t, JobResult result) { - const char *format; - - assert(u); - assert(t >= 0); - assert(t < _JOB_TYPE_MAX); + if (result != JOB_DONE) + manager_flip_auto_status(u->manager, true); DISABLE_WARNING_FORMAT_NONLITERAL; + unit_status_printf(u, job_result_status_table[result], format); + REENABLE_WARNING; - if (t == JOB_START) { - format = job_get_status_message_format(u, t, result); - if (!format) - return; - - switch (result) { - - case JOB_DONE: - if (u->condition_result) - unit_status_printf(u, ANSI_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format); - break; - - case JOB_TIMEOUT: - manager_flip_auto_status(u->manager, true); - unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format); - break; - - case JOB_FAILED: { - _cleanup_free_ char *quoted = NULL; - - quoted = shell_maybe_quote(u->id); - - manager_flip_auto_status(u->manager, true); - unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format); - manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL, "See 'systemctl status %s' for details.", strna(quoted)); - break; - } - - case JOB_DEPENDENCY: - manager_flip_auto_status(u->manager, true); - unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, format); - break; - - case JOB_ASSERT: - manager_flip_auto_status(u->manager, true); - unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "ASSERT" ANSI_HIGHLIGHT_OFF, format); - break; - - case JOB_UNSUPPORTED: - manager_flip_auto_status(u->manager, true); - unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "UNSUPP" ANSI_HIGHLIGHT_OFF, format); - break; - - default: - ; - } - - } else if (t == JOB_STOP || t == JOB_RESTART) { - - format = job_get_status_message_format(u, t, result); - if (!format) - return; - - switch (result) { - - case JOB_TIMEOUT: - manager_flip_auto_status(u->manager, true); - unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format); - break; - - case JOB_DONE: - case JOB_FAILED: - unit_status_printf(u, ANSI_GREEN_ON " OK " ANSI_HIGHLIGHT_OFF, format); - break; - - default: - ; - } - - } else if (t == JOB_VERIFY_ACTIVE) { + if (t == JOB_START && result == JOB_FAILED) { + _cleanup_free_ char *quoted = shell_maybe_quote(u->id); - /* When verify-active detects the unit is inactive, report it. - * Most likely a DEPEND warning from a requisiting unit will - * occur next and it's nice to see what was requisited. */ - if (result == JOB_SKIPPED) - unit_status_printf(u, ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, "%s is not active."); + manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL, + "See 'systemctl status %s' for details.", strna(quoted)); } - - REENABLE_WARNING; } static void job_log_status_message(Unit *u, JobType t, JobResult result) { const char *format; char buf[LINE_MAX]; + sd_id128_t mid; + static const int job_result_log_level[_JOB_RESULT_MAX] = { + [JOB_DONE] = LOG_INFO, + [JOB_CANCELED] = LOG_INFO, + [JOB_TIMEOUT] = LOG_ERR, + [JOB_FAILED] = LOG_ERR, + [JOB_DEPENDENCY] = LOG_WARNING, + [JOB_SKIPPED] = LOG_NOTICE, + [JOB_INVALID] = LOG_INFO, + [JOB_ASSERT] = LOG_WARNING, + [JOB_UNSUPPORTED] = LOG_WARNING, + }; assert(u); assert(t >= 0); @@ -754,7 +728,7 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) { if (log_on_console()) return; - format = job_get_status_message_format_try_harder(u, t, result); + format = job_get_status_message_format(u, t, result); if (!format) return; @@ -762,32 +736,40 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) { snprintf(buf, sizeof(buf), format, unit_description(u)); REENABLE_WARNING; - if (t == JOB_START) { - sd_id128_t mid; - + if (t == JOB_START) mid = result == JOB_DONE ? SD_MESSAGE_UNIT_STARTED : SD_MESSAGE_UNIT_FAILED; - log_struct(result == JOB_DONE ? LOG_INFO : LOG_ERR, - LOG_MESSAGE_ID(mid), + else if (t == JOB_STOP || t == JOB_RESTART) + mid = SD_MESSAGE_UNIT_STOPPED; + else if (t == JOB_RELOAD) + mid = SD_MESSAGE_UNIT_RELOADED; + else { + log_struct(job_result_log_level[result], LOG_UNIT_ID(u), LOG_MESSAGE("%s", buf), "RESULT=%s", job_result_to_string(result), NULL); + return; + } - } else if (t == JOB_STOP) - log_struct(result == JOB_DONE ? LOG_INFO : LOG_ERR, - LOG_MESSAGE_ID(SD_MESSAGE_UNIT_STOPPED), - LOG_UNIT_ID(u), - LOG_MESSAGE("%s", buf), - "RESULT=%s", job_result_to_string(result), - NULL); + log_struct(job_result_log_level[result], + LOG_MESSAGE_ID(mid), + LOG_UNIT_ID(u), + LOG_MESSAGE("%s", buf), + "RESULT=%s", job_result_to_string(result), + NULL); +} - else if (t == JOB_RELOAD) - log_struct(result == JOB_DONE ? LOG_INFO : LOG_ERR, - LOG_MESSAGE_ID(SD_MESSAGE_UNIT_RELOADED), - LOG_UNIT_ID(u), - LOG_MESSAGE("%s", buf), - "RESULT=%s", job_result_to_string(result), - NULL); +static void job_emit_status_message(Unit *u, JobType t, JobResult result) { + + /* No message if the job did not actually do anything due to failed condition. */ + if (t == JOB_START && result == JOB_DONE && !u->condition_result) + return; + + job_log_status_message(u, t, result); + + /* Reload status messages have traditionally not been printed to console. */ + if (t != JOB_RELOAD) + job_print_status_message(u, t, result); } static void job_fail_dependencies(Unit *u, UnitDependency d) { @@ -825,8 +807,7 @@ int job_finish_and_invalidate(Job *j, JobResult result, bool recursive) { log_unit_debug(u, "Job %s/%s finished, result=%s", u->id, job_type_to_string(t), job_result_to_string(result)); - job_print_status_message(u, t, result); - job_log_status_message(u, t, result); + job_emit_status_message(u, t, result); job_add_to_dbus_queue(j); diff --git a/src/core/mount.c b/src/core/mount.c index 851b41351e..bf8e52bf0e 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1025,7 +1025,7 @@ static int mount_reload(Unit *u) { assert(m->state == MOUNT_MOUNTED); mount_enter_remounting(m); - return 0; + return 1; } static int mount_serialize(Unit *u, FILE *f, FDSet *fds) { @@ -1897,7 +1897,6 @@ const UnitVTable mount_vtable = { .finished_start_job = { [JOB_DONE] = "Mounted %s.", [JOB_FAILED] = "Failed to mount %s.", - [JOB_DEPENDENCY] = "Dependency failed for %s.", [JOB_TIMEOUT] = "Timed out mounting %s.", }, .finished_stop_job = { diff --git a/src/core/service.c b/src/core/service.c index d72ff54daa..39a2507b6f 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1974,7 +1974,7 @@ static int service_reload(Unit *u) { assert(s->state == SERVICE_RUNNING || s->state == SERVICE_EXITED); service_enter_reload(s); - return 0; + return 1; } _pure_ static bool service_can_reload(Unit *u) { @@ -3229,13 +3229,10 @@ const UnitVTable service_vtable = { .finished_start_job = { [JOB_DONE] = "Started %s.", [JOB_FAILED] = "Failed to start %s.", - [JOB_DEPENDENCY] = "Dependency failed for %s.", - [JOB_TIMEOUT] = "Timed out starting %s.", }, .finished_stop_job = { [JOB_DONE] = "Stopped %s.", [JOB_FAILED] = "Stopped (with error) %s.", - [JOB_TIMEOUT] = "Timed out stopping %s.", }, }, }; diff --git a/src/core/slice.c b/src/core/slice.c index e52bf71515..064eb5d933 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -297,7 +297,6 @@ const UnitVTable slice_vtable = { .status_message_formats = { .finished_start_job = { [JOB_DONE] = "Created slice %s.", - [JOB_DEPENDENCY] = "Dependency failed for %s.", }, .finished_stop_job = { [JOB_DONE] = "Removed slice %s.", diff --git a/src/core/socket.c b/src/core/socket.c index 693cbc6080..87631f8753 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -2722,7 +2722,6 @@ const UnitVTable socket_vtable = { .finished_start_job = { [JOB_DONE] = "Listening on %s.", [JOB_FAILED] = "Failed to listen on %s.", - [JOB_DEPENDENCY] = "Dependency failed for %s.", [JOB_TIMEOUT] = "Timed out starting %s.", }, .finished_stop_job = { diff --git a/src/core/swap.c b/src/core/swap.c index 193c8c3767..0bc3827ff0 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -1505,7 +1505,6 @@ const UnitVTable swap_vtable = { .finished_start_job = { [JOB_DONE] = "Activated swap %s.", [JOB_FAILED] = "Failed to activate swap %s.", - [JOB_DEPENDENCY] = "Dependency failed for %s.", [JOB_TIMEOUT] = "Timed out activating swap %s.", }, .finished_stop_job = { diff --git a/src/core/target.c b/src/core/target.c index 8817ef21c4..b492a7c4c7 100644 --- a/src/core/target.c +++ b/src/core/target.c @@ -227,7 +227,6 @@ const UnitVTable target_vtable = { .status_message_formats = { .finished_start_job = { [JOB_DONE] = "Reached target %s.", - [JOB_DEPENDENCY] = "Dependency failed for %s.", }, .finished_stop_job = { [JOB_DONE] = "Stopped target %s.", diff --git a/src/core/unit.c b/src/core/unit.c index fac017c57d..dd5e801285 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1318,42 +1318,28 @@ static bool unit_assert_test(Unit *u) { } _pure_ static const char* unit_get_status_message_format(Unit *u, JobType t) { - const UnitStatusMessageFormats *format_table; - - assert(u); - assert(t >= 0); - assert(t < _JOB_TYPE_MAX); - - if (t != JOB_START && t != JOB_STOP) - return NULL; - - format_table = &UNIT_VTABLE(u)->status_message_formats; - if (!format_table) - return NULL; - - return format_table->starting_stopping[t == JOB_STOP]; -} - -_pure_ static const char *unit_get_status_message_format_try_harder(Unit *u, JobType t) { const char *format; + const UnitStatusMessageFormats *format_table; assert(u); - assert(t >= 0); - assert(t < _JOB_TYPE_MAX); + assert(t == JOB_START || t == JOB_STOP || t == JOB_RELOAD); - format = unit_get_status_message_format(u, t); - if (format) - return format; + if (t != JOB_RELOAD) { + format_table = &UNIT_VTABLE(u)->status_message_formats; + if (format_table) { + format = format_table->starting_stopping[t == JOB_STOP]; + if (format) + return format; + } + } /* Return generic strings */ if (t == JOB_START) return "Starting %s."; else if (t == JOB_STOP) return "Stopping %s."; - else if (t == JOB_RELOAD) + else return "Reloading %s."; - - return NULL; } static void unit_status_print_starting_stopping(Unit *u, JobType t) { @@ -1361,12 +1347,7 @@ static void unit_status_print_starting_stopping(Unit *u, JobType t) { assert(u); - /* We only print status messages for selected units on - * selected operations. */ - format = unit_get_status_message_format(u, t); - if (!format) - return; DISABLE_WARNING_FORMAT_NONLITERAL; unit_status_printf(u, "", format); @@ -1388,9 +1369,7 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) { /* We log status messages for all units and all operations. */ - format = unit_get_status_message_format_try_harder(u, t); - if (!format) - return; + format = unit_get_status_message_format(u, t); DISABLE_WARNING_FORMAT_NONLITERAL; snprintf(buf, sizeof(buf), format, unit_description(u)); @@ -1413,6 +1392,15 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) { NULL); } +void unit_status_emit_starting_stopping_reloading(Unit *u, JobType t) { + + unit_status_log_starting_stopping_reloading(u, t); + + /* Reload status messages have traditionally not been printed to console. */ + if (t != JOB_RELOAD) + unit_status_print_starting_stopping(u, t); +} + /* Errors: * -EBADR: This unit type does not support starting. * -EALREADY: Unit is already started. @@ -1423,7 +1411,6 @@ static void unit_status_log_starting_stopping_reloading(Unit *u, JobType t) { int unit_start(Unit *u) { UnitActiveState state; Unit *following; - int r; assert(u); @@ -1477,14 +1464,7 @@ int unit_start(Unit *u) { unit_add_to_dbus_queue(u); - r = UNIT_VTABLE(u)->start(u); - if (r <= 0) - return r; - - /* Log if the start function actually did something */ - unit_status_log_starting_stopping_reloading(u, JOB_START); - unit_status_print_starting_stopping(u, JOB_START); - return r; + return UNIT_VTABLE(u)->start(u); } bool unit_can_start(Unit *u) { @@ -1508,7 +1488,6 @@ bool unit_can_isolate(Unit *u) { int unit_stop(Unit *u) { UnitActiveState state; Unit *following; - int r; assert(u); @@ -1527,13 +1506,7 @@ int unit_stop(Unit *u) { unit_add_to_dbus_queue(u); - r = UNIT_VTABLE(u)->stop(u); - if (r <= 0) - return r; - - unit_status_log_starting_stopping_reloading(u, JOB_STOP); - unit_status_print_starting_stopping(u, JOB_STOP); - return r; + return UNIT_VTABLE(u)->stop(u); } /* Errors: @@ -1544,7 +1517,6 @@ int unit_stop(Unit *u) { int unit_reload(Unit *u) { UnitActiveState state; Unit *following; - int r; assert(u); @@ -1571,12 +1543,7 @@ int unit_reload(Unit *u) { unit_add_to_dbus_queue(u); - r = UNIT_VTABLE(u)->reload(u); - if (r <= 0) - return r; - - unit_status_log_starting_stopping_reloading(u, JOB_RELOAD); - return r; + return UNIT_VTABLE(u)->reload(u); } bool unit_can_reload(Unit *u) { diff --git a/src/core/unit.h b/src/core/unit.h index 9491ef64f9..e60168267f 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -544,6 +544,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants); int unit_coldplug(Unit *u); void unit_status_printf(Unit *u, const char *status, const char *unit_status_msg_format) _printf_(3, 0); +void unit_status_emit_starting_stopping_reloading(Unit *u, JobType t); bool unit_need_daemon_reload(Unit *u); diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index 99115d5e49..c53666ddd0 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -1131,7 +1131,7 @@ static int add_name_change_match(sd_bus *bus, /* If the old name is unset or empty, then * this can match against added names */ - if (!old_owner || old_owner[0] == 0) { + if (isempty(old_owner)) { item->type = KDBUS_ITEM_NAME_ADD; r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m); @@ -1141,7 +1141,7 @@ static int add_name_change_match(sd_bus *bus, /* If the new name is unset or empty, then * this can match against removed names */ - if (!new_owner || new_owner[0] == 0) { + if (isempty(new_owner)) { item->type = KDBUS_ITEM_NAME_REMOVE; r = ioctl(bus->input_fd, KDBUS_CMD_MATCH_ADD, m); @@ -1185,7 +1185,7 @@ static int add_name_change_match(sd_bus *bus, /* If the old name is unset or empty, then this can * match against added ids */ - if (!old_owner || old_owner[0] == 0) { + if (isempty(old_owner)) { item->type = KDBUS_ITEM_ID_ADD; if (!isempty(new_owner)) item->id_change.id = new_owner_id; @@ -1197,7 +1197,7 @@ static int add_name_change_match(sd_bus *bus, /* If thew new name is unset or empty, then this can * match against removed ids */ - if (!new_owner || new_owner[0] == 0) { + if (isempty(new_owner)) { item->type = KDBUS_ITEM_ID_REMOVE; if (!isempty(old_owner)) item->id_change.id = old_owner_id; diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 74ac2ab344..8c6fd8ad30 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -196,19 +196,29 @@ static const NLType rtnl_link_info_data_iptun_types[IFLA_IPTUN_MAX + 1] = { [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NETLINK_TYPE_U32 }, [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NETLINK_TYPE_U16 }, [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NETLINK_TYPE_U16 }, + [IFLA_IPTUN_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16}, + [IFLA_IPTUN_ENCAP_FLAGS] = { .type = NETLINK_TYPE_U16}, + [IFLA_IPTUN_ENCAP_SPORT] = { .type = NETLINK_TYPE_U16}, + [IFLA_IPTUN_ENCAP_DPORT] = { .type = NETLINK_TYPE_U16}, }; static const NLType rtnl_link_info_data_ipgre_types[IFLA_GRE_MAX + 1] = { - [IFLA_GRE_LINK] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GRE_IFLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_OFLAGS] = { .type = NETLINK_TYPE_U16 }, - [IFLA_GRE_IKEY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GRE_OKEY] = { .type = NETLINK_TYPE_U32 }, - [IFLA_GRE_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_GRE_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, - [IFLA_GRE_TTL] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GRE_TOS] = { .type = NETLINK_TYPE_U8 }, - [IFLA_GRE_PMTUDISC] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_IFLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_OFLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_IKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_OKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_GRE_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_GRE_TTL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_TOS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_PMTUDISC] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_FLOWINFO] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_ENCAP_TYPE] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_ENCAP_FLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_ENCAP_SPORT] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_ENCAP_DPORT] = { .type = NETLINK_TYPE_U16 }, }; static const NLType rtnl_link_info_data_ipvti_types[IFLA_VTI_MAX + 1] = { diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 049e33e2a6..e6371ff04d 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -1774,7 +1774,7 @@ static int nologin_timeout_handler( log_info("Creating /run/nologin, blocking further logins..."); - r = write_string_file("/run/nologin", "System is going down.", WRITE_STRING_FILE_ATOMIC); + r = write_string_file("/run/nologin", "System is going down.", WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC); if (r < 0) log_error_errno(r, "Failed to create /run/nologin: %m"); else diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index d446bfa8b3..4aa301b112 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -270,12 +270,18 @@ static int dhcp_lease_lost(Link *link) { if (link->network->dhcp_hostname) { const char *hostname = NULL; - r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname); - if (r >= 0 && hostname) { - r = link_set_hostname(link, ""); + if (!link->network->hostname) + r = sd_dhcp_lease_get_hostname(link->dhcp_lease, &hostname); + else + hostname = link->network->hostname; + + if (r >= 0 || hostname) { + r = link_set_hostname(link, hostname); if (r < 0) - log_link_error(link, - "Failed to reset transient hostname"); + log_link_error_errno(link, r, + "Failed to set transient hostname to '%s': %m", + hostname); + } } @@ -464,8 +470,12 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) { if (link->network->dhcp_hostname) { const char *hostname; - r = sd_dhcp_lease_get_hostname(lease, &hostname); - if (r >= 0) { + if (!link->network->hostname) + r = sd_dhcp_lease_get_hostname(lease, &hostname); + else + hostname = link->network->hostname; + + if (r >= 0 || hostname) { r = link_set_hostname(link, hostname); if (r < 0) log_link_error_errno(link, r, "Failed to set transient hostname to '%s': %m", hostname); @@ -616,14 +626,19 @@ int dhcp4_configure(Link *link) { if (link->network->dhcp_sendhost) { _cleanup_free_ char *hostname = NULL; + const char *hn = NULL; + + if (!link->network->hostname) { + hostname = gethostname_malloc(); + if (!hostname) + return -ENOMEM; - hostname = gethostname_malloc(); - if (!hostname) - return -ENOMEM; + hn = hostname; + } else + hn = link->network->hostname; - if (!is_localhost(hostname)) { - r = sd_dhcp_client_set_hostname(link->dhcp_client, - hostname); + if (!is_localhost(hn)) { + r = sd_dhcp_client_set_hostname(link->dhcp_client, hn); if (r < 0) return r; } diff --git a/src/network/networkd-netdev-gperf.gperf b/src/network/networkd-netdev-gperf.gperf index 010c106610..63258c0376 100644 --- a/src/network/networkd-netdev-gperf.gperf +++ b/src/network/networkd-netdev-gperf.gperf @@ -36,6 +36,7 @@ Tunnel.TOS, config_parse_unsigned, 0, Tunnel.TTL, config_parse_unsigned, 0, offsetof(Tunnel, ttl) Tunnel.DiscoverPathMTU, config_parse_bool, 0, offsetof(Tunnel, pmtudisc) Tunnel.Mode, config_parse_ip6tnl_mode, 0, offsetof(Tunnel, ip6tnl_mode) +Tunnel.IPv6FlowLabel, config_parse_ipv6_flowlabel, 0, offsetof(Tunnel, ipv6_flowlabel) Peer.Name, config_parse_ifname, 0, offsetof(Veth, ifname_peer) Peer.MACAddress, config_parse_hwaddr, 0, offsetof(Veth, mac_peer) VXLAN.Id, config_parse_uint64, 0, offsetof(VxLan, id) diff --git a/src/network/networkd-netdev-tunnel.c b/src/network/networkd-netdev-tunnel.c index 5533fb5c7b..a13edf6936 100644 --- a/src/network/networkd-netdev-tunnel.c +++ b/src/network/networkd-netdev-tunnel.c @@ -33,6 +33,7 @@ #include "conf-parser.h" #define DEFAULT_TNL_HOP_LIMIT 64 +#define IP6_FLOWINFO_FLOWLABEL htonl(0x000FFFFF) static const char* const ip6tnl_mode_table[_NETDEV_IP6_TNL_MODE_MAX] = { [NETDEV_IP6_TNL_MODE_IP6IP6] = "ip6ip6", @@ -264,6 +265,16 @@ static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_netl if (r < 0) return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_TTL attribute: %m"); + if (t->ipv6_flowlabel != _NETDEV_IPV6_FLOWLABEL_INVALID) { + r = sd_netlink_message_append_u32(m, IFLA_IPTUN_FLOWINFO, t->ipv6_flowlabel); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_FLOWINFO attribute: %m"); + } + + r = sd_netlink_message_append_u32(m, IFLA_IPTUN_FLAGS, t->flags); + if (r < 0) + return log_netdev_error_errno(netdev, r, "Could not append IFLA_IPTUN_FLAGS attribute: %m"); + switch (t->ip6tnl_mode) { case NETDEV_IP6_TNL_MODE_IP6IP6: proto = IPPROTO_IPV6; @@ -380,6 +391,52 @@ int config_parse_tunnel_address(const char *unit, return 0; } +static const char* const ipv6_flowlabel_table[_NETDEV_IPV6_FLOWLABEL_MAX] = { + [NETDEV_IPV6_FLOWLABEL_INHERIT] = "inherit", +}; + +DEFINE_STRING_TABLE_LOOKUP(ipv6_flowlabel, IPv6FlowLabel); + +int config_parse_ipv6_flowlabel(const char* unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + IPv6FlowLabel *ipv6_flowlabel = data; + Tunnel *t = userdata; + IPv6FlowLabel s; + int k = 0; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(ipv6_flowlabel); + + s = ipv6_flowlabel_from_string(rvalue); + if (s != _NETDEV_IPV6_FLOWLABEL_INVALID) { + *ipv6_flowlabel = IP6_FLOWINFO_FLOWLABEL; + t->flags |= IP6_TNL_F_USE_ORIG_FLOWLABEL; + } else { + r = config_parse_unsigned(unit, filename, line, section, section_line, lvalue, ltype, rvalue, &k, userdata); + if (r >= 0) { + if (k > 0xFFFFF) + log_syntax(unit, LOG_ERR, filename, line, k, "Failed to parse IPv6 flowlabel option, ignoring: %s", rvalue); + else { + *ipv6_flowlabel = htonl(k) & IP6_FLOWINFO_FLOWLABEL; + t->flags &= ~IP6_TNL_F_USE_ORIG_FLOWLABEL; + } + } + } + + return 0; +} + static void ipip_init(NetDev *n) { Tunnel *t = IPIP(n); @@ -452,6 +509,7 @@ static void ip6tnl_init(NetDev *n) { t->ttl = DEFAULT_TNL_HOP_LIMIT; t->encap_limit = IPV6_DEFAULT_TNL_ENCAP_LIMIT; t->ip6tnl_mode = _NETDEV_IP6_TNL_MODE_INVALID; + t->ipv6_flowlabel = _NETDEV_IPV6_FLOWLABEL_INVALID; } const NetDevVTable ipip_vtable = { diff --git a/src/network/networkd-netdev-tunnel.h b/src/network/networkd-netdev-tunnel.h index 546c9f08b9..47981fbe32 100644 --- a/src/network/networkd-netdev-tunnel.h +++ b/src/network/networkd-netdev-tunnel.h @@ -33,6 +33,12 @@ typedef enum Ip6TnlMode { _NETDEV_IP6_TNL_MODE_INVALID = -1, } Ip6TnlMode; +typedef enum IPv6FlowLabel { + NETDEV_IPV6_FLOWLABEL_INHERIT = 0xFFFFF + 1, + _NETDEV_IPV6_FLOWLABEL_MAX, + _NETDEV_IPV6_FLOWLABEL_INVALID = -1, +} IPv6FlowLabel; + struct Tunnel { NetDev meta; @@ -48,6 +54,7 @@ struct Tunnel { union in_addr_union remote; Ip6TnlMode ip6tnl_mode; + IPv6FlowLabel ipv6_flowlabel; bool pmtudisc; }; @@ -81,3 +88,12 @@ int config_parse_tunnel_address(const char *unit, const char *rvalue, void *data, void *userdata); + +const char *ipv6_flowlabel_to_string(IPv6FlowLabel d) _const_; +IPv6FlowLabel ipv6_flowlabel_from_string(const char *d) _pure_; + +int config_parse_ipv6_flowlabel(const char *unit, const char *filename, + unsigned line, const char *section, + unsigned section_line, const char *lvalue, + int ltype, const char *rvalue, void *data, + void *userdata); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 787fc2ff5b..3a78c3d8a8 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -67,6 +67,7 @@ DHCP.UseHostname, config_parse_bool, 0 DHCP.UseDomains, config_parse_bool, 0, offsetof(Network, dhcp_domains) DHCP.UseRoutes, config_parse_bool, 0, offsetof(Network, dhcp_routes) DHCP.SendHostname, config_parse_bool, 0, offsetof(Network, dhcp_sendhost) +DHCP.Hostname, config_parse_hostname, 0, offsetof(Network, hostname) DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast) DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical) DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index a8e9ef909c..55e735e6bf 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -207,6 +207,7 @@ void network_free(Network *network) { free(network->description); free(network->dhcp_vendor_class_identifier); + free(network->hostname); free(network->mac); @@ -809,3 +810,38 @@ int config_parse_ipv6_privacy_extensions( return 0; } + +int config_parse_hostname(const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + char **hostname = data; + char *hn = NULL; + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + r = config_parse_string(unit, filename, line, section, section_line, + lvalue, ltype, rvalue, &hn, userdata); + if (r < 0) + return r; + + if (!hostname_is_valid(hn)) { + log_syntax(unit, LOG_ERR, filename, line, EINVAL, "hostname is not valid, ignoring assignment: %s", rvalue); + + free(hn); + return 0; + } + + *hostname = hn; + + return 0; +} diff --git a/src/network/networkd.h b/src/network/networkd.h index 81273a8786..fb95f90169 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -133,6 +133,7 @@ struct Network { AddressFamilyBoolean dhcp; DCHPClientIdentifier dhcp_client_identifier; char *dhcp_vendor_class_identifier; + char *hostname; bool dhcp_dns; bool dhcp_ntp; bool dhcp_mtu; @@ -451,3 +452,7 @@ const char* ipv6_privacy_extensions_to_string(IPv6PrivacyExtensions i) _const_; IPv6PrivacyExtensions ipv6_privacy_extensions_from_string(const char *s) _pure_; int config_parse_ipv6_privacy_extensions(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); + + +/* Hostname */ +int config_parse_hostname(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/udev/ata_id/ata_id.c b/src/udev/ata_id/ata_id.c index 7ba0b7fc8f..a59d4c6d50 100644 --- a/src/udev/ata_id/ata_id.c +++ b/src/udev/ata_id/ata_id.c @@ -638,10 +638,20 @@ int main(int argc, char *argv[]) * All other values are reserved. */ word = identify.wyde[108]; - if ((word & 0xf000) == 0x5000) + if ((word & 0xf000) == 0x5000) { + uint64_t wwwn; + + wwwn = identify.wyde[108]; + wwwn <<= 16; + wwwn |= identify.wyde[109]; + wwwn <<= 16; + wwwn |= identify.wyde[110]; + wwwn <<= 16; + wwwn |= identify.wyde[111]; printf("ID_WWN=0x%1$" PRIx64 "\n" "ID_WWN_WITH_EXTENSION=0x%1$" PRIx64 "\n", - identify.octa[108/4]); + wwwn); + } /* from Linux's include/linux/ata.h */ if (identify.wyde[0] == 0x848a || diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 0661f7be00..945845d72c 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -1358,6 +1358,7 @@ static int listen_fds(int *rctrl, int *rnetlink) { * udev.event-timeout=<number of seconds> seconds to wait before terminating an event */ static int parse_proc_cmdline_item(const char *key, const char *value) { + const char *full_key = key; int r; assert(key); @@ -1377,26 +1378,29 @@ static int parse_proc_cmdline_item(const char *key, const char *value) { int prio; prio = util_log_priority(value); + if (prio < 0) + goto invalid; log_set_max_level(prio); } else if (streq(key, "children-max")) { r = safe_atou(value, &arg_children_max); if (r < 0) - log_warning("invalid udev.children-max ignored: %s", value); + goto invalid; } else if (streq(key, "exec-delay")) { r = safe_atoi(value, &arg_exec_delay); if (r < 0) - log_warning("invalid udev.exec-delay ignored: %s", value); + goto invalid; } else if (streq(key, "event-timeout")) { r = safe_atou64(value, &arg_event_timeout_usec); if (r < 0) - log_warning("invalid udev.event-timeout ignored: %s", value); - else { - arg_event_timeout_usec *= USEC_PER_SEC; - arg_event_timeout_warn_usec = (arg_event_timeout_usec / 3) ? : 1; - } + goto invalid; + arg_event_timeout_usec *= USEC_PER_SEC; + arg_event_timeout_warn_usec = (arg_event_timeout_usec / 3) ? : 1; } return 0; +invalid: + log_warning("invalid %s ignored: %s", full_key, value); + return 0; } static void help(void) { diff --git a/src/user-sessions/user-sessions.c b/src/user-sessions/user-sessions.c index ddeb310c3c..e80a7771de 100644 --- a/src/user-sessions/user-sessions.c +++ b/src/user-sessions/user-sessions.c @@ -65,7 +65,7 @@ int main(int argc, char*argv[]) { } else if (streq(argv[1], "stop")) { int r; - r = write_string_file("/run/nologin", "System is going down.", WRITE_STRING_FILE_ATOMIC); + r = write_string_file("/run/nologin", "System is going down.", WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC); if (r < 0) { log_error_errno(r, "Failed to create /run/nologin: %m"); return EXIT_FAILURE; |