Add new flag to allow kexec reboot if kernel is already loaded.
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
#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);
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
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,
/* 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;
} 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" },
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");
if (IN_SET(a,
ACTION_POWEROFF,
ACTION_REBOOT,
+ ACTION_KEXEC,
ACTION_HALT,
ACTION_SUSPEND,
ACTION_HIBERNATE,
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;