[systemd-devel] [PATCH v3] Add reboot to EFI support

Lennart Poettering lennart at poettering.net
Fri Apr 3 04:11:24 PDT 2015


On Fri, 03.04.15 12:40, Jan Janssen (medhefgo at web.de) wrote:

> Changes in v3:
>  - call the feature reboot to firmware everywhere
>  - make the login interface a property and methods to change it and
>    don't couple it with a reboot action
>  - changed/added policykit action defaulting to auth_admin_keep. Please
>    change this if something else is desired.
> 
> The policy kit behavior feels weird to me: if I call bus_verify_polkit()
> with interactive = false, I still get a password prompt for
> CanRebootToFirmware.

Hmm, I figure this is because of the bus message header flag that asks
for interactivity for all calls now. i.e. in systemctl we call
sd_bus_set_allow_interactive_authorization() once, which makes all
calls interactive. This is a general bug in bus-util.c, which I need
to fix. 

Ignore this for now, I will fix this, I added this to the TODO list.

> Is this a bug or am I doing something wrong here? Do I need to make a separate
> get policy (with no auth_admin_keep) for this to work?

>  static int method_inhibit(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
>          _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
>          const char *who, *why, *what, *mode;
> @@ -1970,6 +2063,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("RebootToFirmware", "b", property_get_reboot_to_firmware, 0, SD_BUS_VTABLE_PROPERTY_CONST),
>          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),
> @@ -2023,6 +2117,8 @@ const sd_bus_vtable manager_vtable[] = {
>          SD_BUS_METHOD("CanHibernate", NULL, "s", method_can_hibernate, SD_BUS_VTABLE_UNPRIVILEGED),
>          SD_BUS_METHOD("CanHybridSleep", NULL, "s", method_can_hybrid_sleep, SD_BUS_VTABLE_UNPRIVILEGED),
>          SD_BUS_METHOD("Inhibit", "ssss", "h", method_inhibit, SD_BUS_VTABLE_UNPRIVILEGED),
> +        SD_BUS_METHOD("SetRebootToFirmware", "bb", NULL, method_set_reboot_to_firmware, SD_BUS_VTABLE_UNPRIVILEGED),
> +        SD_BUS_METHOD("CanRebootToFirmware", NULL, "s",
> method_can_reboot_to_firmware, SD_BUS_VTABLE_UNPRIVILEGED),

Looks OK, but I think here too it should say FirmwareSetup rather than
Firmware:

        RebootToFirmwareSetup
        SetRebootToFirmwareSetup
        CanRebootToFirmwareSetup

Similar for the PK action name...

>  
> +bool is_efi_reboot_to_fw_supported(void) {

So far all calls exported by efivars.[ch] used "efi_" is prefix, and I
think this call should too.

Also, the acronym "fw" we already use in the firewall context. I'd
prefer if we would call this efi_reboot_to_firmware_supported() or
so. Similar for the other exported calls.


> +        int r;
> +        uint64_t b;
> +
> +        r = get_os_indications_supported(&b);
> +        return r >= 0;
> +}

I figure assigning this to r first is unnecessary? 

Shouldn't get_os_indications_supported() already act boolean-like,
i.e. return negative on error, 0 when the os indications feature is
not supported and > 0 if it is supported?

Maybe get_os_indications_supported should actually be the exported
function, but optionally take NULL as parameter for those callers that
are not interested in the actual bitfield? With that change
is_efi_reboot_to_fw_supported() and get_os_indications_supported() are
pretty much identical no, and could just be one function?

> +int efi_get_reboot_to_fw(void) {
> +        int r;
> +        uint64_t b;
> +
> +        r = get_os_indications(&b);
> +        return r < 0 ? r : !!(b & EFI_OS_INDICATIONS_BOOT_TO_FW_UI);
> +}

I think this would be easier to read without the ternary operator, and
a simple if.

> +
> +int efi_set_reboot_to_fw(bool value) {
> +        int r;
> +        uint64_t b;
> +
> +        r = get_os_indications(&b);
> +        if (r < 0)
> +                return r;
> +
> +        if (value)
> +                b |= EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
> +        else
> +                b &= ~EFI_OS_INDICATIONS_BOOT_TO_FW_UI;

I think it would be wise to suppress updating the variable if the bit
is already set correctly. After all writes to this memory are
problematic and should be kept at a minimum?

Lennart

-- 
Lennart Poettering, Red Hat


More information about the systemd-devel mailing list