mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-25 23:21:33 +03:00
Merge pull request #10806 from poettering/logind-many-fixes
various smaller fixes and improvements to logind (split out of #10495)
This commit is contained in:
commit
db0ba2a4a4
@ -369,6 +369,8 @@ const char *special_glyph(SpecialGlyph code) {
|
||||
[MDASH] = "-",
|
||||
[ELLIPSIS] = "...",
|
||||
[MU] = "u",
|
||||
[CHECK_MARK] = "+",
|
||||
[CROSS_MARK] = "-",
|
||||
},
|
||||
|
||||
/* UTF-8 */
|
||||
@ -383,6 +385,8 @@ const char *special_glyph(SpecialGlyph code) {
|
||||
[MDASH] = "\342\200\223", /* – */
|
||||
[ELLIPSIS] = "\342\200\246", /* … */
|
||||
[MU] = "\316\274", /* μ */
|
||||
[CHECK_MARK] = "\342\234\223", /* ✓ */
|
||||
[CROSS_MARK] = "\342\234\227", /* ✗ */
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -49,6 +49,8 @@ typedef enum {
|
||||
MDASH,
|
||||
ELLIPSIS,
|
||||
MU,
|
||||
CHECK_MARK,
|
||||
CROSS_MARK,
|
||||
_SPECIAL_GLYPH_MAX
|
||||
} SpecialGlyph;
|
||||
|
||||
|
@ -968,14 +968,28 @@ static int verb_status(int argc, char *argv[], void *userdata) {
|
||||
(void) pager_open(arg_pager_flags);
|
||||
|
||||
if (is_efi_boot()) {
|
||||
static const struct {
|
||||
uint64_t flag;
|
||||
const char *name;
|
||||
} flags[] = {
|
||||
{ EFI_LOADER_FEATURE_BOOT_COUNTING, "Boot counting" },
|
||||
{ EFI_LOADER_FEATURE_CONFIG_TIMEOUT, "Menu timeout control" },
|
||||
{ EFI_LOADER_FEATURE_CONFIG_TIMEOUT_ONE_SHOT, "One-shot menu timeout control" },
|
||||
{ EFI_LOADER_FEATURE_ENTRY_DEFAULT, "Default entry control" },
|
||||
{ EFI_LOADER_FEATURE_ENTRY_ONESHOT, "One-shot entry control" },
|
||||
};
|
||||
|
||||
_cleanup_free_ char *fw_type = NULL, *fw_info = NULL, *loader = NULL, *loader_path = NULL, *stub = NULL;
|
||||
sd_id128_t loader_part_uuid = SD_ID128_NULL;
|
||||
uint64_t loader_features = 0;
|
||||
size_t i;
|
||||
|
||||
read_loader_efi_var("LoaderFirmwareType", &fw_type);
|
||||
read_loader_efi_var("LoaderFirmwareInfo", &fw_info);
|
||||
read_loader_efi_var("LoaderInfo", &loader);
|
||||
read_loader_efi_var("StubInfo", &stub);
|
||||
read_loader_efi_var("LoaderImageIdentifier", &loader_path);
|
||||
(void) efi_loader_get_features(&loader_features);
|
||||
|
||||
if (loader_path)
|
||||
efi_tilt_backslashes(loader_path);
|
||||
@ -992,6 +1006,20 @@ static int verb_status(int argc, char *argv[], void *userdata) {
|
||||
|
||||
printf("Current Boot Loader:\n");
|
||||
printf(" Product: %s%s%s\n", ansi_highlight(), strna(loader), ansi_normal());
|
||||
|
||||
for (i = 0; i < ELEMENTSOF(flags); i++) {
|
||||
|
||||
if (i == 0)
|
||||
printf(" Features: ");
|
||||
else
|
||||
printf(" ");
|
||||
|
||||
if (FLAGS_SET(loader_features, flags[i].flag))
|
||||
printf("%s%s%s %s\n", ansi_highlight_green(), special_glyph(CHECK_MARK), ansi_normal(), flags[i].name);
|
||||
else
|
||||
printf("%s%s%s %s\n", ansi_highlight_red(), special_glyph(CROSS_MARK), ansi_normal(), flags[i].name);
|
||||
}
|
||||
|
||||
if (stub)
|
||||
printf(" Stub: %s\n", stub);
|
||||
if (!sd_id128_is_null(loader_part_uuid))
|
||||
|
@ -39,7 +39,7 @@ UINT64 ticks_freq(VOID) {
|
||||
uefi_call_wrapper(BS->Stall, 1, 1000);
|
||||
ticks_end = ticks_read();
|
||||
|
||||
return (ticks_end - ticks_start) * 1000;
|
||||
return (ticks_end - ticks_start) * 1000UL;
|
||||
}
|
||||
|
||||
UINT64 time_usec(VOID) {
|
||||
@ -56,7 +56,7 @@ UINT64 time_usec(VOID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1000 * 1000 * ticks / freq;
|
||||
return 1000UL * 1000UL * ticks / freq;
|
||||
}
|
||||
|
||||
EFI_STATUS parse_boolean(CHAR8 *v, BOOLEAN *b) {
|
||||
|
@ -566,6 +566,17 @@ int manager_spawn_autovt(Manager *m, unsigned vtnr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool manager_is_lid_closed(Manager *m) {
|
||||
Iterator i;
|
||||
Button *b;
|
||||
|
||||
HASHMAP_FOREACH(b, m->buttons, i)
|
||||
if (b->lid_closed)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool manager_is_docked(Manager *m) {
|
||||
Iterator i;
|
||||
Button *b;
|
||||
@ -670,15 +681,13 @@ bool manager_is_docked_or_external_displays(Manager *m) {
|
||||
bool manager_is_on_external_power(void) {
|
||||
int r;
|
||||
|
||||
/* For now we only check for AC power, but 'external power' can apply
|
||||
* to anything that isn't an internal battery */
|
||||
/* For now we only check for AC power, but 'external power' can apply to anything that isn't an internal
|
||||
* battery */
|
||||
r = on_ac_power();
|
||||
if (r < 0)
|
||||
log_warning_errno(r, "Failed to read AC power status: %m");
|
||||
else if (r > 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return r != 0; /* Treat failure as 'on AC' */
|
||||
}
|
||||
|
||||
bool manager_all_buttons_ignored(Manager *m) {
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "bus-error.h"
|
||||
#include "bus-unit-util.h"
|
||||
#include "bus-util.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "device-util.h"
|
||||
#include "dirent-util.h"
|
||||
#include "efivars.h"
|
||||
@ -26,7 +27,6 @@
|
||||
#include "mkdir.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "cgroup-util.h"
|
||||
#include "selinux-util.h"
|
||||
#include "sleep-config.h"
|
||||
#include "special.h"
|
||||
@ -274,6 +274,8 @@ static int property_get_scheduled_shutdown(
|
||||
|
||||
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_handle_action, handle_action, HandleAction);
|
||||
static BUS_DEFINE_PROPERTY_GET(property_get_docked, "b", Manager, manager_is_docked_or_external_displays);
|
||||
static BUS_DEFINE_PROPERTY_GET(property_get_lid_closed, "b", Manager, manager_is_lid_closed);
|
||||
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_on_external_power, "b", manager_is_on_external_power);
|
||||
static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_compat_user_tasks_max, "t", CGROUP_LIMIT_MAX);
|
||||
static BUS_DEFINE_PROPERTY_GET_REF(property_get_hashmap_size, "t", Hashmap *, (uint64_t) hashmap_size);
|
||||
|
||||
@ -2265,11 +2267,13 @@ static int method_can_shutdown_or_sleep(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (r > 0 && !result)
|
||||
result = "yes";
|
||||
else if (challenge && (!result || streq(result, "yes")))
|
||||
result = "challenge";
|
||||
else
|
||||
if (r > 0) {
|
||||
if (!result)
|
||||
result = "yes";
|
||||
} else if (challenge) {
|
||||
if (!result || streq(result, "yes"))
|
||||
result = "challenge";
|
||||
} else
|
||||
result = "no";
|
||||
}
|
||||
|
||||
@ -2456,7 +2460,7 @@ static int method_can_reboot_to_firmware_setup(
|
||||
r = efi_reboot_to_firmware_supported();
|
||||
if (r < 0) {
|
||||
if (r != -EOPNOTSUPP)
|
||||
log_warning_errno(errno, "Failed to determine whether reboot to firmware is supported: %m");
|
||||
log_warning_errno(r, "Failed to determine whether reboot to firmware is supported: %m");
|
||||
|
||||
return sd_bus_reply_method_return(message, "s", "na");
|
||||
}
|
||||
@ -2645,7 +2649,7 @@ const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_PROPERTY("KillOnlyUsers", "as", NULL, offsetof(Manager, kill_only_users), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("KillExcludeUsers", "as", NULL, offsetof(Manager, kill_exclude_users), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("KillUserProcesses", "b", NULL, offsetof(Manager, kill_user_processes), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RebootToFirmwareSetup", "b", property_get_reboot_to_firmware_setup, 0, 0),
|
||||
SD_BUS_PROPERTY("IdleHint", "b", property_get_idle_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHint", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
SD_BUS_PROPERTY("IdleSinceHintMonotonic", "t", property_get_idle_since_hint, 0, SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
|
||||
@ -2666,6 +2670,8 @@ const sd_bus_vtable manager_vtable[] = {
|
||||
SD_BUS_PROPERTY("PreparingForSleep", "b", property_get_preparing, 0, 0),
|
||||
SD_BUS_PROPERTY("ScheduledShutdown", "(st)", property_get_scheduled_shutdown, 0, 0),
|
||||
SD_BUS_PROPERTY("Docked", "b", property_get_docked, 0, 0),
|
||||
SD_BUS_PROPERTY("LidClosed", "b", property_get_lid_closed, 0, 0),
|
||||
SD_BUS_PROPERTY("OnExternalPower", "b", property_get_on_external_power, 0, 0),
|
||||
SD_BUS_PROPERTY("RemoveIPC", "b", bus_property_get_bool, offsetof(Manager, remove_ipc), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("RuntimeDirectorySize", "t", NULL, offsetof(Manager, runtime_dir_size), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
SD_BUS_PROPERTY("InhibitorsMax", "t", NULL, offsetof(Manager, inhibitors_max), SD_BUS_VTABLE_PROPERTY_CONST),
|
||||
|
@ -146,6 +146,7 @@ int manager_get_idle_hint(Manager *m, dual_timestamp *t);
|
||||
int manager_get_user_by_pid(Manager *m, pid_t pid, User **user);
|
||||
int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session);
|
||||
|
||||
bool manager_is_lid_closed(Manager *m);
|
||||
bool manager_is_docked_or_external_displays(Manager *m);
|
||||
bool manager_is_on_external_power(void);
|
||||
bool manager_all_buttons_ignored(Manager *m);
|
||||
|
@ -345,6 +345,7 @@
|
||||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_active>yes</allow_active>
|
||||
</defaults>
|
||||
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.reboot</annotate>
|
||||
</action>
|
||||
|
||||
<action id="org.freedesktop.login1.set-wall-message">
|
||||
|
@ -246,6 +246,24 @@ int efi_get_variable(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p) {
|
||||
_cleanup_free_ void *s = NULL;
|
||||
size_t ss = 0;
|
||||
int r;
|
||||
char *x;
|
||||
|
||||
r = efi_get_variable(vendor, name, NULL, &s, &ss);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
x = utf16_to_utf8(s, ss);
|
||||
if (!x)
|
||||
return -ENOMEM;
|
||||
|
||||
*p = x;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int efi_set_variable(
|
||||
sd_id128_t vendor,
|
||||
const char *name,
|
||||
@ -326,22 +344,14 @@ finish:
|
||||
return r;
|
||||
}
|
||||
|
||||
int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p) {
|
||||
_cleanup_free_ void *s = NULL;
|
||||
size_t ss = 0;
|
||||
int r;
|
||||
char *x;
|
||||
int efi_set_variable_string(sd_id128_t vendor, const char *name, const char *v) {
|
||||
_cleanup_free_ char16_t *u16 = NULL;
|
||||
|
||||
r = efi_get_variable(vendor, name, NULL, &s, &ss);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
x = utf16_to_utf8(s, ss);
|
||||
if (!x)
|
||||
u16 = utf8_to_utf16(v, strlen(v));
|
||||
if (!u16)
|
||||
return -ENOMEM;
|
||||
|
||||
*p = x;
|
||||
return 0;
|
||||
return efi_set_variable(vendor, name, u16, (char16_strlen(u16) + 1) * sizeof(char16_t));
|
||||
}
|
||||
|
||||
static size_t utf16_size(const uint16_t *s) {
|
||||
@ -761,6 +771,16 @@ int efi_loader_get_device_part_uuid(sd_id128_t *u) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool efi_loader_entry_name_valid(const char *s) {
|
||||
if (isempty(s))
|
||||
return false;
|
||||
|
||||
if (strlen(s) > FILENAME_MAX) /* Make sure entry names fit in filenames */
|
||||
return false;
|
||||
|
||||
return in_charset(s, ALPHANUMERICAL "-");
|
||||
}
|
||||
|
||||
int efi_loader_get_entries(char ***ret) {
|
||||
_cleanup_free_ char16_t *entries = NULL;
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
@ -779,7 +799,7 @@ int efi_loader_get_entries(char ***ret) {
|
||||
/* The variable contains a series of individually NUL terminated UTF-16 strings. */
|
||||
|
||||
for (i = 0, start = 0;; i++) {
|
||||
char *decoded;
|
||||
_cleanup_free_ char *decoded = NULL;
|
||||
bool end;
|
||||
|
||||
/* Is this the end of the variable's data? */
|
||||
@ -795,9 +815,12 @@ int efi_loader_get_entries(char ***ret) {
|
||||
if (!decoded)
|
||||
return -ENOMEM;
|
||||
|
||||
r = strv_consume(&l, decoded);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (efi_loader_entry_name_valid(decoded)) {
|
||||
r = strv_consume(&l, TAKE_PTR(decoded));
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else
|
||||
log_debug("Ignoring invalid loader entry '%s'.", decoded);
|
||||
|
||||
/* We reached the end of the variable */
|
||||
if (end)
|
||||
@ -822,3 +845,53 @@ char *efi_tilt_backslashes(char *s) {
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int efi_loader_get_features(uint64_t *ret) {
|
||||
_cleanup_free_ void *v = NULL;
|
||||
size_t s;
|
||||
int r;
|
||||
|
||||
if (!is_efi_boot()) {
|
||||
*ret = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = efi_get_variable(EFI_VENDOR_LOADER, "LoaderFeatures", NULL, &v, &s);
|
||||
if (r == -ENOENT) {
|
||||
_cleanup_free_ char *info = NULL;
|
||||
|
||||
/* The new (v240+) LoaderFeatures variable is not supported, let's see if it's systemd-boot at all */
|
||||
r = efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderInfo", &info);
|
||||
if (r < 0) {
|
||||
if (r != -ENOENT)
|
||||
return r;
|
||||
|
||||
/* Variable not set, definitely means not systemd-boot */
|
||||
|
||||
} else if (first_word(info, "systemd-boot")) {
|
||||
|
||||
/* An older systemd-boot version. Let's hardcode the feature set, since it was pretty
|
||||
* static in all its versions. */
|
||||
|
||||
*ret = EFI_LOADER_FEATURE_CONFIG_TIMEOUT |
|
||||
EFI_LOADER_FEATURE_ENTRY_DEFAULT |
|
||||
EFI_LOADER_FEATURE_ENTRY_ONESHOT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* No features supported */
|
||||
*ret = 0;
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (s != sizeof(uint64_t)) {
|
||||
log_debug("LoaderFeatures EFI variable doesn't have the right size.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(ret, v, sizeof(uint64_t));
|
||||
return 0;
|
||||
}
|
||||
|
@ -18,6 +18,12 @@
|
||||
#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0000000000000002
|
||||
#define EFI_VARIABLE_RUNTIME_ACCESS 0x0000000000000004
|
||||
|
||||
#define EFI_LOADER_FEATURE_CONFIG_TIMEOUT (UINT64_C(1) << 0)
|
||||
#define EFI_LOADER_FEATURE_CONFIG_TIMEOUT_ONE_SHOT (UINT64_C(1) << 1)
|
||||
#define EFI_LOADER_FEATURE_ENTRY_DEFAULT (UINT64_C(1) << 2)
|
||||
#define EFI_LOADER_FEATURE_ENTRY_ONESHOT (UINT64_C(1) << 3)
|
||||
#define EFI_LOADER_FEATURE_BOOT_COUNTING (UINT64_C(1) << 4)
|
||||
|
||||
#if ENABLE_EFI
|
||||
|
||||
bool is_efi_boot(void);
|
||||
@ -28,8 +34,9 @@ int efi_get_reboot_to_firmware(void);
|
||||
int efi_set_reboot_to_firmware(bool value);
|
||||
|
||||
int efi_get_variable(sd_id128_t vendor, const char *name, uint32_t *attribute, void **value, size_t *size);
|
||||
int efi_set_variable(sd_id128_t vendor, const char *name, const void *value, size_t size);
|
||||
int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p);
|
||||
int efi_set_variable(sd_id128_t vendor, const char *name, const void *value, size_t size);
|
||||
int efi_set_variable_string(sd_id128_t vendor, const char *name, const char *p);
|
||||
|
||||
int efi_get_boot_option(uint16_t nr, char **title, sd_id128_t *part_uuid, char **path, bool *active);
|
||||
int efi_add_boot_option(uint16_t id, const char *title, uint32_t part, uint64_t pstart, uint64_t psize, sd_id128_t part_uuid, const char *path);
|
||||
@ -43,6 +50,10 @@ int efi_loader_get_boot_usec(usec_t *firmware, usec_t *loader);
|
||||
|
||||
int efi_loader_get_entries(char ***ret);
|
||||
|
||||
bool efi_loader_entry_name_valid(const char *s);
|
||||
|
||||
int efi_loader_get_features(uint64_t *ret);
|
||||
|
||||
#else
|
||||
|
||||
static inline bool is_efi_boot(void) {
|
||||
@ -73,11 +84,15 @@ static inline int efi_get_variable(sd_id128_t vendor, const char *name, uint32_t
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p) {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int efi_set_variable(sd_id128_t vendor, const char *name, const void *value, size_t size) {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int efi_get_variable_string(sd_id128_t vendor, const char *name, char **p) {
|
||||
static inline int efi_set_variable_string(sd_id128_t vendor, const char *name, const char *p) {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
@ -117,6 +132,10 @@ static inline int efi_loader_get_entries(char ***ret) {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline int efi_loader_get_features(uint64_t *ret) {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
char *efi_tilt_backslashes(char *s);
|
||||
|
@ -65,7 +65,7 @@ static void test_keymaps(void) {
|
||||
|
||||
#define dump_glyph(x) log_info(STRINGIFY(x) ": %s", special_glyph(x))
|
||||
static void dump_special_glyphs(void) {
|
||||
assert_cc(MU + 1 == _SPECIAL_GLYPH_MAX);
|
||||
assert_cc(CROSS_MARK + 1 == _SPECIAL_GLYPH_MAX);
|
||||
|
||||
log_info("/* %s */", __func__);
|
||||
|
||||
@ -80,6 +80,9 @@ static void dump_special_glyphs(void) {
|
||||
dump_glyph(ARROW);
|
||||
dump_glyph(MDASH);
|
||||
dump_glyph(ELLIPSIS);
|
||||
dump_glyph(MU);
|
||||
dump_glyph(CHECK_MARK);
|
||||
dump_glyph(CROSS_MARK);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
Loading…
Reference in New Issue
Block a user