mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
logind: Add new flag for kexec reboot
Add new flag to allow kexec reboot if kernel is already loaded.
This commit is contained in:
parent
a93af34a40
commit
0d96caa5c0
@ -555,10 +555,13 @@ node /org/freedesktop/login1 {
|
||||
extendability, defined as follows:</para>
|
||||
<programlisting>
|
||||
#define SD_LOGIND_ROOT_CHECK_INHIBITORS (UINT64_C(1) << 0)
|
||||
#define SD_LOGIND_KEXEC_REBOOT (UINT64_C(1) << 1)
|
||||
</programlisting>
|
||||
<para> When the <varname>flags</varname> is 0 then these methods behave just like the versions
|
||||
without flags. When <constant>SD_LOGIND_ROOT_CHECK_INHIBITORS</constant> (0x01) is set, active
|
||||
inhibitors are honoured for privileged users too.</para>
|
||||
inhibitors are honoured for privileged users too. When <constant>SD_LOGIND_KEXEC_REBOOT</constant>
|
||||
(0x02) is set, then <function>RebootWithFlags()</function> perform kexec reboot if kexec
|
||||
kernel is loaded.</para>
|
||||
|
||||
<para><function>SetRebootParameter()</function> sets a parameter for a subsequent reboot operation.
|
||||
See the description of <command>reboot</command> in
|
||||
|
@ -5,12 +5,13 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#define SD_LOGIND_ROOT_CHECK_INHIBITORS (UINT64_C(1) << 0)
|
||||
#define SD_LOGIND_KEXEC_REBOOT (UINT64_C(1) << 1)
|
||||
|
||||
/* For internal use only */
|
||||
#define SD_LOGIND_INTERACTIVE (UINT64_C(1) << 63)
|
||||
|
||||
#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC (SD_LOGIND_ROOT_CHECK_INHIBITORS)
|
||||
#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_ALL (SD_LOGIND_ROOT_CHECK_INHIBITORS|SD_LOGIND_INTERACTIVE)
|
||||
#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC (SD_LOGIND_ROOT_CHECK_INHIBITORS|SD_LOGIND_KEXEC_REBOOT)
|
||||
#define SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_ALL (SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC|SD_LOGIND_INTERACTIVE)
|
||||
|
||||
bool session_id_valid(const char *id);
|
||||
|
||||
|
@ -1880,6 +1880,8 @@ static int method_do_shutdown_or_sleep(
|
||||
return r;
|
||||
if ((flags & ~SD_LOGIND_SHUTDOWN_AND_SLEEP_FLAGS_PUBLIC) != 0)
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
|
||||
if (!streq(unit_name, SPECIAL_REBOOT_TARGET) && (flags & SD_LOGIND_KEXEC_REBOOT))
|
||||
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
|
||||
} else {
|
||||
/* Old style method: no flags parameter, but interactive bool passed as boolean in
|
||||
* payload. Let's convert this argument to the new-style flags parameter for our internal
|
||||
@ -1893,6 +1895,9 @@ static int method_do_shutdown_or_sleep(
|
||||
flags = interactive ? SD_LOGIND_INTERACTIVE : 0;
|
||||
}
|
||||
|
||||
if ((flags & SD_LOGIND_KEXEC_REBOOT) && kexec_loaded())
|
||||
unit_name = SPECIAL_KEXEC_TARGET;
|
||||
|
||||
/* Don't allow multiple jobs being executed at the same time */
|
||||
if (m->action_what > 0)
|
||||
return sd_bus_error_setf(error, BUS_ERROR_OPERATION_IN_PROGRESS,
|
||||
|
@ -161,7 +161,7 @@ int halt_main(void) {
|
||||
|
||||
/* Try logind if we are a normal user and no special mode applies. Maybe polkit allows us to
|
||||
* shutdown the machine. */
|
||||
if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT, ACTION_HALT)) {
|
||||
if (IN_SET(arg_action, ACTION_POWEROFF, ACTION_REBOOT, ACTION_KEXEC, ACTION_HALT)) {
|
||||
r = logind_reboot(arg_action);
|
||||
if (r >= 0)
|
||||
return r;
|
||||
|
@ -50,6 +50,7 @@ int logind_reboot(enum action a) {
|
||||
} actions[_ACTION_MAX] = {
|
||||
[ACTION_POWEROFF] = { "PowerOff", "power off system" },
|
||||
[ACTION_REBOOT] = { "Reboot", "reboot system" },
|
||||
[ACTION_KEXEC] = { "Reboot", "kexec reboot system" },
|
||||
[ACTION_HALT] = { "Halt", "halt system" },
|
||||
[ACTION_SUSPEND] = { "Suspend", "suspend system" },
|
||||
[ACTION_HIBERNATE] = { "Hibernate", "hibernate system" },
|
||||
@ -79,6 +80,7 @@ int logind_reboot(enum action a) {
|
||||
return 0;
|
||||
|
||||
SET_FLAG(flags, SD_LOGIND_ROOT_CHECK_INHIBITORS, arg_check_inhibitors > 0);
|
||||
SET_FLAG(flags, SD_LOGIND_KEXEC_REBOOT, a == ACTION_KEXEC);
|
||||
|
||||
method_with_flags = strjoina(actions[a].method, "WithFlags");
|
||||
|
||||
|
@ -201,6 +201,7 @@ int start_special(int argc, char *argv[], void *userdata) {
|
||||
if (IN_SET(a,
|
||||
ACTION_POWEROFF,
|
||||
ACTION_REBOOT,
|
||||
ACTION_KEXEC,
|
||||
ACTION_HALT,
|
||||
ACTION_SUSPEND,
|
||||
ACTION_HIBERNATE,
|
||||
@ -220,9 +221,9 @@ int start_special(int argc, char *argv[], void *userdata) {
|
||||
|
||||
arg_no_block = true;
|
||||
|
||||
} else if (IN_SET(a, ACTION_EXIT, ACTION_KEXEC))
|
||||
/* Since exit/kexec are so close in behaviour to power-off/reboot, let's also make
|
||||
* them asynchronous, in order to not confuse the user needlessly with unexpected
|
||||
} else if (IN_SET(a, ACTION_EXIT))
|
||||
/* Since exit is so close in behaviour to power-off/reboot, let's also make
|
||||
* it asynchronous, in order to not confuse the user needlessly with unexpected
|
||||
* behaviour. */
|
||||
arg_no_block = true;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user