mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-10-27 01:55:32 +03:00
service: rename Type=finish to Type=oneshot and allow multiple ExecStart= lines for oneshot services
In contrast to the other service types oneshot services are usually not long lasting and there's not necessarily a single clean main process for them. This change allows multiple ExecStart= lines for this type of services so that the admin/developer doesn't have to arbitrarily pick on of various sequential commands as the "main one".
This commit is contained in:
parent
00b07cb3f3
commit
34e9ba669e
2
fixme
2
fixme
@ -71,8 +71,6 @@
|
|||||||
|
|
||||||
* be more forgiving when parsing unit files, when encountering incorrect lines with assignments
|
* be more forgiving when parsing unit files, when encountering incorrect lines with assignments
|
||||||
|
|
||||||
* ExecStart= mehrfach bei Type=finish
|
|
||||||
|
|
||||||
* move runlevel symlinks to /lib
|
* move runlevel symlinks to /lib
|
||||||
|
|
||||||
* agetty darf nicht mit emergency.service kollidieren
|
* agetty darf nicht mit emergency.service kollidieren
|
||||||
|
@ -119,7 +119,7 @@
|
|||||||
start-up type for this service
|
start-up type for this service
|
||||||
unit. One of <option>simple</option>,
|
unit. One of <option>simple</option>,
|
||||||
<option>forking</option>,
|
<option>forking</option>,
|
||||||
<option>finish</option>,
|
<option>oneshot</option>,
|
||||||
<option>dbus</option>,
|
<option>dbus</option>,
|
||||||
<option>notify</option>.</para>
|
<option>notify</option>.</para>
|
||||||
|
|
||||||
@ -158,7 +158,7 @@
|
|||||||
exits.</para>
|
exits.</para>
|
||||||
|
|
||||||
<para>Behaviour of
|
<para>Behaviour of
|
||||||
<option>finish</option> is similar
|
<option>oneshot</option> is similar
|
||||||
to <option>simple</option>, however
|
to <option>simple</option>, however
|
||||||
it is expected that the process has to
|
it is expected that the process has to
|
||||||
exit before systemd starts follow-up
|
exit before systemd starts follow-up
|
||||||
|
@ -295,7 +295,6 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
|
|||||||
DBUS_TYPE_INVALID))
|
DBUS_TYPE_INVALID))
|
||||||
goto oom;
|
goto oom;
|
||||||
} else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnitByPID")) {
|
} else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnitByPID")) {
|
||||||
const char *name;
|
|
||||||
Unit *u;
|
Unit *u;
|
||||||
uint32_t pid;
|
uint32_t pid;
|
||||||
|
|
||||||
|
179
src/service.c
179
src/service.c
@ -834,8 +834,9 @@ static int service_verify(Service *s) {
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->exec_command[SERVICE_EXEC_START]->command_next) {
|
if (s->type != SERVICE_ONESHOT &&
|
||||||
log_error("%s has more than one ExecStart setting. Refusing.", s->meta.id);
|
s->exec_command[SERVICE_EXEC_START]->command_next) {
|
||||||
|
log_error("%s has more than one ExecStart setting, which is only allowed for Type=oneshot services. Refusing.", s->meta.id);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1250,7 +1251,7 @@ static int service_coldplug(Unit *u) {
|
|||||||
if ((s->deserialized_state == SERVICE_START &&
|
if ((s->deserialized_state == SERVICE_START &&
|
||||||
(s->type == SERVICE_FORKING ||
|
(s->type == SERVICE_FORKING ||
|
||||||
s->type == SERVICE_DBUS ||
|
s->type == SERVICE_DBUS ||
|
||||||
s->type == SERVICE_FINISH ||
|
s->type == SERVICE_ONESHOT ||
|
||||||
s->type == SERVICE_NOTIFY)) ||
|
s->type == SERVICE_NOTIFY)) ||
|
||||||
s->deserialized_state == SERVICE_START_POST ||
|
s->deserialized_state == SERVICE_START_POST ||
|
||||||
s->deserialized_state == SERVICE_RUNNING ||
|
s->deserialized_state == SERVICE_RUNNING ||
|
||||||
@ -1711,15 +1712,18 @@ static void service_enter_start(Service *s) {
|
|||||||
assert(s);
|
assert(s);
|
||||||
|
|
||||||
assert(s->exec_command[SERVICE_EXEC_START]);
|
assert(s->exec_command[SERVICE_EXEC_START]);
|
||||||
assert(!s->exec_command[SERVICE_EXEC_START]->command_next);
|
assert(!s->exec_command[SERVICE_EXEC_START]->command_next || s->type == SERVICE_ONESHOT);
|
||||||
|
|
||||||
if (s->type == SERVICE_FORKING)
|
if (s->type == SERVICE_FORKING)
|
||||||
service_unwatch_control_pid(s);
|
service_unwatch_control_pid(s);
|
||||||
else
|
else
|
||||||
service_unwatch_main_pid(s);
|
service_unwatch_main_pid(s);
|
||||||
|
|
||||||
|
s->control_command_id = SERVICE_EXEC_START;
|
||||||
|
s->control_command = s->exec_command[SERVICE_EXEC_START];
|
||||||
|
|
||||||
if ((r = service_spawn(s,
|
if ((r = service_spawn(s,
|
||||||
s->exec_command[SERVICE_EXEC_START],
|
s->control_command,
|
||||||
s->type == SERVICE_FORKING || s->type == SERVICE_DBUS || s->type == SERVICE_NOTIFY,
|
s->type == SERVICE_FORKING || s->type == SERVICE_DBUS || s->type == SERVICE_NOTIFY,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
@ -1741,17 +1745,14 @@ static void service_enter_start(Service *s) {
|
|||||||
/* For forking services we wait until the start
|
/* For forking services we wait until the start
|
||||||
* process exited. */
|
* process exited. */
|
||||||
|
|
||||||
s->control_command_id = SERVICE_EXEC_START;
|
|
||||||
s->control_command = s->exec_command[SERVICE_EXEC_START];
|
|
||||||
|
|
||||||
s->control_pid = pid;
|
s->control_pid = pid;
|
||||||
service_set_state(s, SERVICE_START);
|
service_set_state(s, SERVICE_START);
|
||||||
|
|
||||||
} else if (s->type == SERVICE_FINISH ||
|
} else if (s->type == SERVICE_ONESHOT ||
|
||||||
s->type == SERVICE_DBUS ||
|
s->type == SERVICE_DBUS ||
|
||||||
s->type == SERVICE_NOTIFY) {
|
s->type == SERVICE_NOTIFY) {
|
||||||
|
|
||||||
/* For finishing services we wait until the start
|
/* For oneshot services we wait until the start
|
||||||
* process exited, too, but it is our main process. */
|
* process exited, too, but it is our main process. */
|
||||||
|
|
||||||
/* For D-Bus services we know the main pid right away,
|
/* For D-Bus services we know the main pid right away,
|
||||||
@ -1854,7 +1855,7 @@ fail:
|
|||||||
service_enter_stop(s, false);
|
service_enter_stop(s, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void service_run_next(Service *s, bool success) {
|
static void service_run_next_control(Service *s, bool success) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
@ -1864,8 +1865,9 @@ static void service_run_next(Service *s, bool success) {
|
|||||||
if (!success)
|
if (!success)
|
||||||
s->failure = true;
|
s->failure = true;
|
||||||
|
|
||||||
s->control_command = s->control_command->command_next;
|
assert(s->control_command_id != SERVICE_EXEC_START);
|
||||||
|
|
||||||
|
s->control_command = s->control_command->command_next;
|
||||||
service_unwatch_control_pid(s);
|
service_unwatch_control_pid(s);
|
||||||
|
|
||||||
if ((r = service_spawn(s,
|
if ((r = service_spawn(s,
|
||||||
@ -1883,7 +1885,7 @@ static void service_run_next(Service *s, bool success) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
log_warning("%s failed to run next task: %s", s->meta.id, strerror(-r));
|
log_warning("%s failed to run next control task: %s", s->meta.id, strerror(-r));
|
||||||
|
|
||||||
if (s->state == SERVICE_START_PRE)
|
if (s->state == SERVICE_START_PRE)
|
||||||
service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
|
service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
|
||||||
@ -1895,6 +1897,43 @@ fail:
|
|||||||
service_enter_stop(s, false);
|
service_enter_stop(s, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void service_run_next_main(Service *s, bool success) {
|
||||||
|
pid_t pid;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
assert(s->control_command);
|
||||||
|
assert(s->control_command->command_next);
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
s->failure = true;
|
||||||
|
|
||||||
|
assert(s->control_command_id == SERVICE_EXEC_START);
|
||||||
|
assert(s->type == SERVICE_ONESHOT);
|
||||||
|
|
||||||
|
s->control_command = s->control_command->command_next;
|
||||||
|
service_unwatch_main_pid(s);
|
||||||
|
|
||||||
|
if ((r = service_spawn(s,
|
||||||
|
s->control_command,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
s->notify_access != NOTIFY_NONE,
|
||||||
|
&pid)) < 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
service_set_main_pid(s, pid);
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
log_warning("%s failed to run next main task: %s", s->meta.id, strerror(-r));
|
||||||
|
service_enter_stop(s, false);
|
||||||
|
}
|
||||||
|
|
||||||
static int service_start(Unit *u) {
|
static int service_start(Unit *u) {
|
||||||
Service *s = SERVICE(u);
|
Service *s = SERVICE(u);
|
||||||
|
|
||||||
@ -2226,14 +2265,13 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
|||||||
|
|
||||||
if (s->main_pid == pid) {
|
if (s->main_pid == pid) {
|
||||||
|
|
||||||
exec_status_exit(&s->main_exec_status, pid, code, status);
|
|
||||||
s->main_pid = 0;
|
s->main_pid = 0;
|
||||||
|
exec_status_exit(&s->main_exec_status, pid, code, status);
|
||||||
|
|
||||||
if (s->type != SERVICE_FORKING) {
|
if (s->type != SERVICE_FORKING && s->control_command) {
|
||||||
assert(s->exec_command[SERVICE_EXEC_START]);
|
s->control_command->exec_status = s->main_exec_status;
|
||||||
s->exec_command[SERVICE_EXEC_START]->exec_status = s->main_exec_status;
|
|
||||||
|
|
||||||
if (s->exec_command[SERVICE_EXEC_START]->ignore)
|
if (s->control_command->ignore)
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2241,51 +2279,69 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
|||||||
"%s: main process exited, code=%s, status=%i", u->meta.id, sigchld_code_to_string(code), status);
|
"%s: main process exited, code=%s, status=%i", u->meta.id, sigchld_code_to_string(code), status);
|
||||||
s->failure = s->failure || !success;
|
s->failure = s->failure || !success;
|
||||||
|
|
||||||
/* The service exited, so the service is officially
|
if (s->control_command &&
|
||||||
* gone. */
|
s->control_command->command_next &&
|
||||||
|
success) {
|
||||||
|
|
||||||
switch (s->state) {
|
/* There is another command to *
|
||||||
|
* execute, so let's do that. */
|
||||||
|
|
||||||
case SERVICE_START_POST:
|
log_debug("%s running next main command for state %s", u->meta.id, service_state_to_string(s->state));
|
||||||
case SERVICE_RELOAD:
|
service_run_next_main(s, success);
|
||||||
case SERVICE_STOP:
|
|
||||||
/* Need to wait until the operation is
|
|
||||||
* done */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SERVICE_START:
|
} else {
|
||||||
if (s->type == SERVICE_FINISH) {
|
|
||||||
/* This was our main goal, so let's go on */
|
/* The service exited, so the service is officially
|
||||||
if (success)
|
* gone. */
|
||||||
service_enter_start_post(s);
|
|
||||||
else
|
s->control_command = NULL;
|
||||||
service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
|
s->control_command_id = _SERVICE_EXEC_COMMAND_INVALID;
|
||||||
|
|
||||||
|
switch (s->state) {
|
||||||
|
|
||||||
|
case SERVICE_START_POST:
|
||||||
|
case SERVICE_RELOAD:
|
||||||
|
case SERVICE_STOP:
|
||||||
|
/* Need to wait until the operation is
|
||||||
|
* done */
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
assert(s->type == SERVICE_DBUS || s->type == SERVICE_NOTIFY);
|
|
||||||
|
|
||||||
/* Fall through */
|
case SERVICE_START:
|
||||||
|
if (s->type == SERVICE_ONESHOT) {
|
||||||
|
/* This was our main goal, so let's go on */
|
||||||
|
if (success)
|
||||||
|
service_enter_start_post(s);
|
||||||
|
else
|
||||||
|
service_enter_signal(s, SERVICE_FINAL_SIGTERM, false);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
assert(s->type == SERVICE_DBUS || s->type == SERVICE_NOTIFY);
|
||||||
|
|
||||||
|
/* Fall through */
|
||||||
|
}
|
||||||
|
|
||||||
|
case SERVICE_RUNNING:
|
||||||
|
service_enter_running(s, success);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SERVICE_STOP_SIGTERM:
|
||||||
|
case SERVICE_STOP_SIGKILL:
|
||||||
|
|
||||||
|
if (!control_pid_good(s))
|
||||||
|
service_enter_stop_post(s, success);
|
||||||
|
|
||||||
|
/* If there is still a control process, wait for that first */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert_not_reached("Uh, main process died at wrong time.");
|
||||||
}
|
}
|
||||||
|
|
||||||
case SERVICE_RUNNING:
|
|
||||||
service_enter_running(s, success);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SERVICE_STOP_SIGTERM:
|
|
||||||
case SERVICE_STOP_SIGKILL:
|
|
||||||
|
|
||||||
if (!control_pid_good(s))
|
|
||||||
service_enter_stop_post(s, success);
|
|
||||||
|
|
||||||
/* If there is still a control process, wait for that first */
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert_not_reached("Uh, main process died at wrong time.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (s->control_pid == pid) {
|
} else if (s->control_pid == pid) {
|
||||||
|
|
||||||
|
s->control_pid = 0;
|
||||||
|
|
||||||
if (s->control_command) {
|
if (s->control_command) {
|
||||||
exec_status_exit(&s->control_command->exec_status, pid, code, status);
|
exec_status_exit(&s->control_command->exec_status, pid, code, status);
|
||||||
|
|
||||||
@ -2293,22 +2349,19 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
|
|||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->control_pid = 0;
|
log_full(success ? LOG_DEBUG : LOG_NOTICE,
|
||||||
|
|
||||||
log_full(success ? LOG_DEBUG : LOG_NOTICE,
|
|
||||||
"%s: control process exited, code=%s status=%i", u->meta.id, sigchld_code_to_string(code), status);
|
"%s: control process exited, code=%s status=%i", u->meta.id, sigchld_code_to_string(code), status);
|
||||||
s->failure = s->failure || !success;
|
s->failure = s->failure || !success;
|
||||||
|
|
||||||
/* If we are shutting things down anyway we
|
if (s->control_command &&
|
||||||
* don't care about failing commands. */
|
s->control_command->command_next &&
|
||||||
|
success) {
|
||||||
if (s->control_command && s->control_command->command_next && success) {
|
|
||||||
|
|
||||||
/* There is another command to *
|
/* There is another command to *
|
||||||
* execute, so let's do that. */
|
* execute, so let's do that. */
|
||||||
|
|
||||||
log_debug("%s running next command for state %s", u->meta.id, service_state_to_string(s->state));
|
log_debug("%s running next control command for state %s", u->meta.id, service_state_to_string(s->state));
|
||||||
service_run_next(s, success);
|
service_run_next_control(s, success);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* No further commands for this step, so let's
|
/* No further commands for this step, so let's
|
||||||
@ -2822,7 +2875,7 @@ DEFINE_STRING_TABLE_LOOKUP(service_restart, ServiceRestart);
|
|||||||
static const char* const service_type_table[_SERVICE_TYPE_MAX] = {
|
static const char* const service_type_table[_SERVICE_TYPE_MAX] = {
|
||||||
[SERVICE_SIMPLE] = "simple",
|
[SERVICE_SIMPLE] = "simple",
|
||||||
[SERVICE_FORKING] = "forking",
|
[SERVICE_FORKING] = "forking",
|
||||||
[SERVICE_FINISH] = "finish",
|
[SERVICE_ONESHOT] = "oneshot",
|
||||||
[SERVICE_DBUS] = "dbus",
|
[SERVICE_DBUS] = "dbus",
|
||||||
[SERVICE_NOTIFY] = "notify"
|
[SERVICE_NOTIFY] = "notify"
|
||||||
};
|
};
|
||||||
|
@ -58,7 +58,7 @@ typedef enum ServiceRestart {
|
|||||||
typedef enum ServiceType {
|
typedef enum ServiceType {
|
||||||
SERVICE_SIMPLE, /* we fork and go on right-away (i.e. modern socket activated daemons) */
|
SERVICE_SIMPLE, /* we fork and go on right-away (i.e. modern socket activated daemons) */
|
||||||
SERVICE_FORKING, /* forks by itself (i.e. traditional daemons) */
|
SERVICE_FORKING, /* forks by itself (i.e. traditional daemons) */
|
||||||
SERVICE_FINISH, /* we fork and wait until the program finishes (i.e. programs like fsck which run and need to finish before we continue) */
|
SERVICE_ONESHOT, /* we fork and wait until the program finishes (i.e. programs like fsck which run and need to finish before we continue) */
|
||||||
SERVICE_DBUS, /* we fork and wait until a specific D-Bus name appears on the bus */
|
SERVICE_DBUS, /* we fork and wait until a specific D-Bus name appears on the bus */
|
||||||
SERVICE_NOTIFY, /* we fork and wait until a daemon sends us a ready message with sd_notify() */
|
SERVICE_NOTIFY, /* we fork and wait until a daemon sends us a ready message with sd_notify() */
|
||||||
_SERVICE_TYPE_MAX,
|
_SERVICE_TYPE_MAX,
|
||||||
|
@ -5,7 +5,7 @@ Description=Permission Enforcement checker
|
|||||||
ExecStart=/usr/bin/id
|
ExecStart=/usr/bin/id
|
||||||
ExecStartPost=/usr/bin/env
|
ExecStartPost=/usr/bin/env
|
||||||
ExecStartPost=/bin/sleep 5
|
ExecStartPost=/bin/sleep 5
|
||||||
Type=finish
|
Type=oneshot
|
||||||
Capabilities=all= cap_dac_override=eip
|
Capabilities=all= cap_dac_override=eip
|
||||||
User=nobody
|
User=nobody
|
||||||
Group=nobody
|
Group=nobody
|
||||||
|
@ -12,7 +12,7 @@ Requires=shutdown.target umount.target
|
|||||||
After=shutdown.target umount.target
|
After=shutdown.target umount.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
Environment=RUNLEVEL=0
|
Environment=RUNLEVEL=0
|
||||||
ExecStart=/etc/rc.shutdown
|
ExecStart=/etc/rc.shutdown
|
||||||
|
@ -12,7 +12,7 @@ Requires=shutdown.target umount.target
|
|||||||
After=shutdown.target umount.target
|
After=shutdown.target umount.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
Environment=RUNLEVEL=0
|
Environment=RUNLEVEL=0
|
||||||
ExecStart=/etc/rc.shutdown
|
ExecStart=/etc/rc.shutdown
|
||||||
|
@ -12,7 +12,7 @@ Requires=shutdown.target umount.target
|
|||||||
After=shutdown.target umount.target
|
After=shutdown.target umount.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
Environment=RUNLEVEL=6
|
Environment=RUNLEVEL=6
|
||||||
ExecStart=/etc/rc.shutdown
|
ExecStart=/etc/rc.shutdown
|
||||||
|
@ -12,7 +12,7 @@ Requires=shutdown.target umount.target killall.service
|
|||||||
After=shutdown.target umount.target killall.service
|
After=shutdown.target umount.target killall.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
Environment=INIT_HALT=HALT RUNLEVEL=0
|
Environment=INIT_HALT=HALT RUNLEVEL=0
|
||||||
ExecStart=/etc/init.d/halt start
|
ExecStart=/etc/init.d/halt start
|
||||||
|
@ -12,7 +12,7 @@ After=shutdown.target
|
|||||||
RefuseManualStart=yes
|
RefuseManualStart=yes
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
ExecStart=-/etc/init.d/killall start
|
ExecStart=-/etc/init.d/killall start
|
||||||
StandardOutput=tty
|
StandardOutput=tty
|
||||||
|
@ -11,7 +11,7 @@ Before=getty@tty1.service
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=-/usr/bin/plymouth quit
|
ExecStart=-/usr/bin/plymouth quit
|
||||||
Type=finish
|
Type=oneshot
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
@ -12,7 +12,7 @@ Requires=shutdown.target umount.target killall.service
|
|||||||
After=shutdown.target umount.target killall.service
|
After=shutdown.target umount.target killall.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
Environment=RUNLEVEL=0
|
Environment=RUNLEVEL=0
|
||||||
ExecStart=/etc/init.d/halt start
|
ExecStart=/etc/init.d/halt start
|
||||||
|
@ -12,7 +12,7 @@ Requires=shutdown.target umount.target killall.service
|
|||||||
After=shutdown.target umount.target killall.service
|
After=shutdown.target umount.target killall.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
Environment=RUNLEVEL=6
|
Environment=RUNLEVEL=6
|
||||||
ExecStart=/etc/init.d/reboot start
|
ExecStart=/etc/init.d/reboot start
|
||||||
|
@ -12,7 +12,7 @@ Requires=shutdown.target umount.target killall.service
|
|||||||
After=shutdown.target umount.target killall.service
|
After=shutdown.target umount.target killall.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
Environment=INIT_HALT=HALT RC_DOWN_HARDDISK=yes
|
Environment=INIT_HALT=HALT RC_DOWN_HARDDISK=yes
|
||||||
ExecStart=/etc/init.d/shutdown.sh
|
ExecStart=/etc/init.d/shutdown.sh
|
||||||
|
@ -12,7 +12,7 @@ After=shutdown.target
|
|||||||
RefuseManualStart=yes
|
RefuseManualStart=yes
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
ExecStart=-/etc/init.d/killprocs start
|
ExecStart=-/etc/init.d/killprocs start
|
||||||
StandardOutput=tty
|
StandardOutput=tty
|
||||||
|
@ -12,7 +12,7 @@ Requires=shutdown.target umount.target killall.service
|
|||||||
After=shutdown.target umount.target killall.service
|
After=shutdown.target umount.target killall.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
Environment=RC_DOWN_HARDDISK=yes
|
Environment=RC_DOWN_HARDDISK=yes
|
||||||
ExecStart=/etc/init.d/shutdown.sh
|
ExecStart=/etc/init.d/shutdown.sh
|
||||||
|
@ -12,7 +12,7 @@ Requires=shutdown.target umount.target killall.service
|
|||||||
After=shutdown.target umount.target killall.service
|
After=shutdown.target umount.target killall.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
ExecStart=/etc/init.d/reboot.sh
|
ExecStart=/etc/init.d/reboot.sh
|
||||||
StandardOutput=tty
|
StandardOutput=tty
|
||||||
|
@ -5,5 +5,5 @@ Requires=shutdown.target
|
|||||||
After=shutdown.target
|
After=shutdown.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ExecStart=@SYSTEMCTL@ --session daemon-exit
|
ExecStart=@SYSTEMCTL@ --session daemon-exit
|
||||||
|
@ -12,7 +12,7 @@ Requires=shutdown.target umount.target
|
|||||||
After=shutdown.target umount.target
|
After=shutdown.target umount.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
Environment=INIT_HALT=HALT RUNLEVEL=0 COLD_BOOT=1
|
Environment=INIT_HALT=HALT RUNLEVEL=0 COLD_BOOT=1
|
||||||
ExecStart=/etc/init.d/halt
|
ExecStart=/etc/init.d/halt
|
||||||
|
@ -12,7 +12,7 @@ Requires=shutdown.target umount.target
|
|||||||
After=shutdown.target umount.target
|
After=shutdown.target umount.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
Environment=COLD_BOOT=1
|
Environment=COLD_BOOT=1
|
||||||
ExecStart=/etc/init.d/halt
|
ExecStart=/etc/init.d/halt
|
||||||
|
@ -12,7 +12,7 @@ Requires=shutdown.target umount.target
|
|||||||
After=shutdown.target umount.target
|
After=shutdown.target umount.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ValidNoProcess=yes
|
ValidNoProcess=yes
|
||||||
Environment=COLD_BOOT=1
|
Environment=COLD_BOOT=1
|
||||||
ExecStart=/etc/init.d/reboot
|
ExecStart=/etc/init.d/reboot
|
||||||
|
@ -11,5 +11,5 @@ DefaultDependencies=no
|
|||||||
After=runlevel1.target runlevel2.target runlevel3.target runlevel4.target runlevel5.target auditd.service
|
After=runlevel1.target runlevel2.target runlevel3.target runlevel4.target runlevel5.target auditd.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ExecStart=-@rootlibexecdir@/systemd-update-utmp runlevel
|
ExecStart=-@rootlibexecdir@/systemd-update-utmp runlevel
|
||||||
|
@ -12,5 +12,5 @@ Before=killall.service
|
|||||||
Conflicts=systemd-update-utmp-runlevel.service
|
Conflicts=systemd-update-utmp-runlevel.service
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=finish
|
Type=oneshot
|
||||||
ExecStart=-@rootlibexecdir@/systemd-update-utmp shutdown
|
ExecStart=-@rootlibexecdir@/systemd-update-utmp shutdown
|
||||||
|
Loading…
Reference in New Issue
Block a user