Skip to content

Commit b2deaaf

Browse files
authored
Merge pull request #27584 from rphibel/add-restartquick-option
service: add new RestartMode option
2 parents 25cae3e + 2a39b91 commit b2deaaf

23 files changed

+133
-5
lines changed

man/org.freedesktop.systemd1.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2598,6 +2598,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
25982598
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
25992599
readonly s Restart = '...';
26002600
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
2601+
readonly s RestartMode = '...';
2602+
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
26012603
readonly s PIDFile = '...';
26022604
readonly s NotifyAccess = '...';
26032605
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
@@ -3243,6 +3245,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
32433245

32443246
<!--property Restart is not documented!-->
32453247

3248+
<!--property RestartMode is not documented!-->
3249+
32463250
<!--property PIDFile is not documented!-->
32473251

32483252
<!--property NotifyAccess is not documented!-->
@@ -3823,6 +3827,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
38233827

38243828
<variablelist class="dbus-property" generated="True" extra-ref="Restart"/>
38253829

3830+
<variablelist class="dbus-property" generated="True" extra-ref="RestartMode"/>
3831+
38263832
<variablelist class="dbus-property" generated="True" extra-ref="PIDFile"/>
38273833

38283834
<variablelist class="dbus-property" generated="True" extra-ref="NotifyAccess"/>

man/systemd.service.xml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,28 @@
897897
</listitem>
898898
</varlistentry>
899899

900+
<varlistentry>
901+
<term><varname>RestartMode=</varname></term>
902+
903+
<listitem>
904+
<para>Takes a string value that specifies how a service should restart:
905+
<itemizedlist>
906+
<listitem><para>If set to <option>normal</option> (the default), the service restarts by
907+
going through a failed/inactive state.</para></listitem>
908+
909+
<listitem><para>If set to <option>direct</option>, the service transitions to the activating
910+
state directly during auto-restart, skipping failed/inactive state.
911+
<varname>ExecStopPost=</varname> is invoked.
912+
<varname>OnSuccess=</varname> and <varname>OnFailure=</varname> are skipped.</para></listitem>
913+
</itemizedlist>
914+
</para>
915+
916+
<para>This option is useful in cases where a dependency can fail temporarily
917+
but we don't want these temporary failures to make the dependent units fail.
918+
When this option is set to <option>direct</option>, dependent units are not notified of these temporary failures.</para>
919+
</listitem>
920+
</varlistentry>
921+
900922
<varlistentry>
901923
<term><varname>SuccessExitStatus=</varname></term>
902924

src/core/dbus-service.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_type, service_type, ServiceType
3333
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_exit_type, service_exit_type, ServiceExitType);
3434
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_result, service_result, ServiceResult);
3535
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart, service_restart, ServiceRestart);
36+
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_restart_mode, service_restart_mode, ServiceRestartMode);
3637
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_emergency_action, emergency_action, EmergencyAction);
3738
static BUS_DEFINE_PROPERTY_GET2(property_get_notify_access, "s", Service, service_get_notify_access, notify_access_to_string);
3839
static BUS_DEFINE_PROPERTY_GET(property_get_restart_usec_next, "t", Service, service_restart_usec_next);
@@ -322,6 +323,7 @@ const sd_bus_vtable bus_service_vtable[] = {
322323
SD_BUS_PROPERTY("Type", "s", property_get_type, offsetof(Service, type), SD_BUS_VTABLE_PROPERTY_CONST),
323324
SD_BUS_PROPERTY("ExitType", "s", property_get_exit_type, offsetof(Service, exit_type), SD_BUS_VTABLE_PROPERTY_CONST),
324325
SD_BUS_PROPERTY("Restart", "s", property_get_restart, offsetof(Service, restart), SD_BUS_VTABLE_PROPERTY_CONST),
326+
SD_BUS_PROPERTY("RestartMode", "s", property_get_restart_mode, offsetof(Service, restart_mode), SD_BUS_VTABLE_PROPERTY_CONST),
325327
SD_BUS_PROPERTY("PIDFile", "s", NULL, offsetof(Service, pid_file), SD_BUS_VTABLE_PROPERTY_CONST),
326328
SD_BUS_PROPERTY("NotifyAccess", "s", property_get_notify_access, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
327329
SD_BUS_PROPERTY("RestartUSec", "t", bus_property_get_usec, offsetof(Service, restart_usec), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -512,6 +514,7 @@ static BUS_DEFINE_SET_TRANSIENT_PARSE(notify_access, NotifyAccess, notify_access
512514
static BUS_DEFINE_SET_TRANSIENT_PARSE(service_type, ServiceType, service_type_from_string);
513515
static BUS_DEFINE_SET_TRANSIENT_PARSE(service_exit_type, ServiceExitType, service_exit_type_from_string);
514516
static BUS_DEFINE_SET_TRANSIENT_PARSE(service_restart, ServiceRestart, service_restart_from_string);
517+
static BUS_DEFINE_SET_TRANSIENT_PARSE(service_restart_mode, ServiceRestartMode, service_restart_mode_from_string);
515518
static BUS_DEFINE_SET_TRANSIENT_PARSE(oom_policy, OOMPolicy, oom_policy_from_string);
516519
static BUS_DEFINE_SET_TRANSIENT_STRING_WITH_CHECK(bus_name, sd_bus_service_name_is_valid);
517520
static BUS_DEFINE_SET_TRANSIENT_PARSE(timeout_failure_mode, ServiceTimeoutFailureMode, service_timeout_failure_mode_from_string);
@@ -660,6 +663,9 @@ static int bus_service_set_transient_property(
660663
if (streq(name, "Restart"))
661664
return bus_set_transient_service_restart(u, name, &s->restart, message, flags, error);
662665

666+
if (streq(name, "RestartMode"))
667+
return bus_set_transient_service_restart_mode(u, name, &s->restart_mode, message, flags, error);
668+
663669
if (streq(name, "RestartPreventExitStatus"))
664670
return bus_set_transient_exit_status(u, name, &s->restart_prevent_status, message, flags, error);
665671

src/core/job.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ static void job_merge_into_installed(Job *j, Job *other) {
217217
j->ignore_order = j->ignore_order || other->ignore_order;
218218
}
219219

220-
Job* job_install(Job *j) {
220+
Job* job_install(Job *j, JobMode mode) {
221221
Job **pj;
222222
Job *uj;
223223

@@ -235,7 +235,7 @@ Job* job_install(Job *j) {
235235
/* not conflicting, i.e. mergeable */
236236

237237
if (uj->state == JOB_WAITING ||
238-
(job_type_allows_late_merge(j->type) && job_type_is_superset(uj->type, j->type))) {
238+
(job_type_allows_late_merge(j->type) && mode != JOB_RESTART_DEPENDENCIES && job_type_is_superset(uj->type, j->type))) {
239239
job_merge_into_installed(uj, j);
240240
log_unit_debug(uj->unit,
241241
"Merged %s/%s into installed job %s/%s as %"PRIu32,

src/core/job.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ Job* job_new(Unit *unit, JobType type);
169169
Job* job_new_raw(Unit *unit);
170170
void job_unlink(Job *job);
171171
Job* job_free(Job *job);
172-
Job* job_install(Job *j);
172+
Job* job_install(Job *j, JobMode mode);
173173
int job_install_deserialized(Job *j);
174174
void job_uninstall(Job *j);
175175
void job_dump(Job *j, FILE *f, const char *prefix);

src/core/load-fragment-gperf.gperf.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ Service.RebootArgument, config_parse_unit_string_printf,
427427
Service.Type, config_parse_service_type, 0, offsetof(Service, type)
428428
Service.ExitType, config_parse_service_exit_type, 0, offsetof(Service, exit_type)
429429
Service.Restart, config_parse_service_restart, 0, offsetof(Service, restart)
430+
Service.RestartMode, config_parse_service_restart_mode, 0, offsetof(Service, restart_mode)
430431
Service.PermissionsStartOnly, config_parse_bool, 0, offsetof(Service, permissions_start_only)
431432
Service.RootDirectoryStartOnly, config_parse_bool, 0, offsetof(Service, root_directory_start_only)
432433
Service.RemainAfterExit, config_parse_bool, 0, offsetof(Service, remain_after_exit)

src/core/load-fragment.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_preserve_mode, exec_preserve_mode, Ex
142142
DEFINE_CONFIG_PARSE_ENUM(config_parse_service_type, service_type, ServiceType, "Failed to parse service type");
143143
DEFINE_CONFIG_PARSE_ENUM(config_parse_service_exit_type, service_exit_type, ServiceExitType, "Failed to parse service exit type");
144144
DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart, service_restart, ServiceRestart, "Failed to parse service restart specifier");
145+
DEFINE_CONFIG_PARSE_ENUM(config_parse_service_restart_mode, service_restart_mode, ServiceRestartMode, "Failed to parse service restart mode");
145146
DEFINE_CONFIG_PARSE_ENUM(config_parse_service_timeout_failure_mode, service_timeout_failure_mode, ServiceTimeoutFailureMode, "Failed to parse timeout failure mode");
146147
DEFINE_CONFIG_PARSE_ENUM(config_parse_socket_bind, socket_address_bind_ipv6_only_or_bool, SocketAddressBindIPv6Only, "Failed to parse bind IPv6 only value");
147148
DEFINE_CONFIG_PARSE_ENUM(config_parse_oom_policy, oom_policy, OOMPolicy, "Failed to parse OOM policy");
@@ -6299,6 +6300,7 @@ void unit_dump_config_items(FILE *f) {
62996300
{ config_parse_service_type, "SERVICETYPE" },
63006301
{ config_parse_service_exit_type, "SERVICEEXITTYPE" },
63016302
{ config_parse_service_restart, "SERVICERESTART" },
6303+
{ config_parse_service_restart_mode, "SERVICERESTARTMODE" },
63026304
{ config_parse_service_timeout_failure_mode, "TIMEOUTMODE" },
63036305
{ config_parse_kill_mode, "KILLMODE" },
63046306
{ config_parse_signal, "SIGNAL" },

src/core/load-fragment.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_service_timeout_failure_mode);
4141
CONFIG_PARSER_PROTOTYPE(config_parse_service_type);
4242
CONFIG_PARSER_PROTOTYPE(config_parse_service_exit_type);
4343
CONFIG_PARSER_PROTOTYPE(config_parse_service_restart);
44+
CONFIG_PARSER_PROTOTYPE(config_parse_service_restart_mode);
4445
CONFIG_PARSER_PROTOTYPE(config_parse_socket_bindtodevice);
4546
CONFIG_PARSER_PROTOTYPE(config_parse_exec_output);
4647
CONFIG_PARSER_PROTOTYPE(config_parse_exec_input);

src/core/service.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2011,7 +2011,8 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
20112011
* are only transitionary and followed by an automatic restart. We have fine-grained
20122012
* low-level states for this though so that software can distinguish the permanent UNIT_INACTIVE
20132013
* state from this transitionary UNIT_INACTIVE state by looking at the low-level states. */
2014-
service_set_state(s, restart_state);
2014+
if (s->restart_mode != SERVICE_RESTART_MODE_DIRECT)
2015+
service_set_state(s, restart_state);
20152016

20162017
r = service_arm_timer(s, /* relative= */ true, service_restart_usec_next(s));
20172018
if (r < 0)
@@ -5009,6 +5010,13 @@ static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
50095010

50105011
DEFINE_STRING_TABLE_LOOKUP(service_restart, ServiceRestart);
50115012

5013+
static const char* const service_restart_mode_table[_SERVICE_RESTART_MODE_MAX] = {
5014+
[SERVICE_RESTART_MODE_NORMAL] = "normal",
5015+
[SERVICE_RESTART_MODE_DIRECT] = "direct",
5016+
};
5017+
5018+
DEFINE_STRING_TABLE_LOOKUP(service_restart_mode, ServiceRestartMode);
5019+
50125020
static const char* const service_type_table[_SERVICE_TYPE_MAX] = {
50135021
[SERVICE_SIMPLE] = "simple",
50145022
[SERVICE_FORKING] = "forking",

src/core/service.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ typedef enum ServiceTimeoutFailureMode {
9191
_SERVICE_TIMEOUT_FAILURE_MODE_INVALID = -EINVAL,
9292
} ServiceTimeoutFailureMode;
9393

94+
typedef enum ServiceRestartMode {
95+
SERVICE_RESTART_MODE_NORMAL,
96+
SERVICE_RESTART_MODE_DIRECT,
97+
_SERVICE_RESTART_MODE_MAX,
98+
_SERVICE_RESTART_MODE_INVALID = -EINVAL,
99+
} ServiceRestartMode;
100+
94101
struct ServiceFDStore {
95102
Service *service;
96103

@@ -108,6 +115,7 @@ struct Service {
108115
ServiceType type;
109116
ServiceExitType exit_type;
110117
ServiceRestart restart;
118+
ServiceRestartMode restart_mode;
111119
ExitStatusSet restart_prevent_status;
112120
ExitStatusSet restart_force_status;
113121
ExitStatusSet success_status;
@@ -249,6 +257,9 @@ usec_t service_restart_usec_next(Service *s);
249257
const char* service_restart_to_string(ServiceRestart i) _const_;
250258
ServiceRestart service_restart_from_string(const char *s) _pure_;
251259

260+
const char* service_restart_mode_to_string(ServiceRestartMode i) _const_;
261+
ServiceRestartMode service_restart_mode_from_string(const char *s) _pure_;
262+
252263
const char* service_type_to_string(ServiceType i) _const_;
253264
ServiceType service_type_from_string(const char *s) _pure_;
254265

0 commit comments

Comments
 (0)