1
1
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:
Lennart Poettering 2018-11-16 17:52:11 +01:00 committed by GitHub
commit db0ba2a4a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 181 additions and 35 deletions

View File

@ -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", /* ✗ */
},
};

View File

@ -49,6 +49,8 @@ typedef enum {
MDASH,
ELLIPSIS,
MU,
CHECK_MARK,
CROSS_MARK,
_SPECIAL_GLYPH_MAX
} SpecialGlyph;

View File

@ -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))

View File

@ -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) {

View File

@ -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) {

View File

@ -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),

View File

@ -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);

View File

@ -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">

View File

@ -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;
}

View File

@ -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);

View File

@ -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[]) {