mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-09 02:48:38 +00:00
Inihbit all power management actions using logind when updating
Fixes https://github.com/fwupd/fwupd/issues/1814
This commit is contained in:
parent
f50ff2c27e
commit
cfde249435
@ -364,6 +364,7 @@ mkdir -p --mode=0700 $RPM_BUILD_ROOT%{_localstatedir}/lib/fwupd/gnupg
|
|||||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_uefi.so
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_uefi.so
|
||||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_uefi_recovery.so
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_uefi_recovery.so
|
||||||
%endif
|
%endif
|
||||||
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_logind.so
|
||||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_logitech_hidpp.so
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_logitech_hidpp.so
|
||||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_upower.so
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_upower.so
|
||||||
%{_libdir}/fwupd-plugins-3/libfu_plugin_vli.so
|
%{_libdir}/fwupd-plugins-3/libfu_plugin_vli.so
|
||||||
|
13
plugins/logind/README.md
Normal file
13
plugins/logind/README.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
logind Support
|
||||||
|
==============
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
|
||||||
|
This plugin is used to ensure that the machine does not enter a low power mode
|
||||||
|
when updates are being performed.
|
||||||
|
|
||||||
|
Vendor ID Security
|
||||||
|
------------------
|
||||||
|
|
||||||
|
This protocol does not create a device and thus requires no vendor ID set.
|
132
plugins/logind/fu-plugin-logind.c
Normal file
132
plugins/logind/fu-plugin-logind.c
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Richard Hughes <richard@hughsie.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: LGPL-2.1+
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <gio/gunixfdlist.h>
|
||||||
|
#include <glib/gstdio.h>
|
||||||
|
|
||||||
|
#include "fu-plugin-vfuncs.h"
|
||||||
|
#include "fu-hash.h"
|
||||||
|
|
||||||
|
struct FuPluginData {
|
||||||
|
GDBusProxy *logind_proxy;
|
||||||
|
gint logind_fd;
|
||||||
|
};
|
||||||
|
|
||||||
|
void
|
||||||
|
fu_plugin_init (FuPlugin *plugin)
|
||||||
|
{
|
||||||
|
fu_plugin_set_build_hash (plugin, FU_BUILD_HASH);
|
||||||
|
fu_plugin_alloc_data (plugin, sizeof (FuPluginData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fu_plugin_destroy (FuPlugin *plugin)
|
||||||
|
{
|
||||||
|
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||||
|
if (data->logind_fd != 0)
|
||||||
|
g_close (data->logind_fd, NULL);
|
||||||
|
if (data->logind_proxy != NULL)
|
||||||
|
g_object_unref (data->logind_proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
fu_plugin_startup (FuPlugin *plugin, GError **error)
|
||||||
|
{
|
||||||
|
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||||
|
data->logind_proxy =
|
||||||
|
g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM,
|
||||||
|
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS |
|
||||||
|
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES,
|
||||||
|
NULL,
|
||||||
|
"org.freedesktop.login1",
|
||||||
|
"/org/freedesktop/login1",
|
||||||
|
"org.freedesktop.login1.Manager",
|
||||||
|
NULL,
|
||||||
|
error);
|
||||||
|
if (data->logind_proxy == NULL) {
|
||||||
|
g_prefix_error (error, "failed to connect to logind: ");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (g_dbus_proxy_get_name_owner (data->logind_proxy) == NULL) {
|
||||||
|
g_set_error (error,
|
||||||
|
FWUPD_ERROR,
|
||||||
|
FWUPD_ERROR_NOT_SUPPORTED,
|
||||||
|
"no owner for %s",
|
||||||
|
g_dbus_proxy_get_name (data->logind_proxy));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
fu_plugin_update_prepare (FuPlugin *plugin,
|
||||||
|
FwupdInstallFlags flags,
|
||||||
|
FuDevice *device,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||||
|
g_autoptr(GError) error_local = NULL;
|
||||||
|
g_autoptr(GUnixFDList) out_fd_list = NULL;
|
||||||
|
g_autoptr(GVariant) res = NULL;
|
||||||
|
const gchar *what = "shutdown:sleep:idle:handle-power-key:handle-suspend-key:"
|
||||||
|
"handle-hibernate-key:handle-lid-switch";
|
||||||
|
|
||||||
|
/* already inhibited */
|
||||||
|
if (data->logind_fd != 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
/* not yet connected */
|
||||||
|
if (data->logind_proxy == NULL) {
|
||||||
|
g_warning ("no logind connection to use");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* block shutdown and idle */
|
||||||
|
res = g_dbus_proxy_call_with_unix_fd_list_sync (data->logind_proxy,
|
||||||
|
"Inhibit",
|
||||||
|
g_variant_new ("(ssss)",
|
||||||
|
what,
|
||||||
|
PACKAGE_NAME,
|
||||||
|
"Firmware Update in Progress",
|
||||||
|
"block"),
|
||||||
|
G_DBUS_CALL_FLAGS_NONE,
|
||||||
|
-1,
|
||||||
|
NULL, /* fd_list */
|
||||||
|
&out_fd_list,
|
||||||
|
NULL, /* GCancellable */
|
||||||
|
&error_local);
|
||||||
|
if (res == NULL) {
|
||||||
|
g_warning ("failed to Inhibit using logind: %s", error_local->message);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* keep fd as cookie */
|
||||||
|
if (g_unix_fd_list_get_length (out_fd_list) != 1) {
|
||||||
|
g_warning ("invalid response from logind");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
data->logind_fd = g_unix_fd_list_get (out_fd_list, 0, NULL);
|
||||||
|
g_debug ("opened logind fd %i", data->logind_fd);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
fu_plugin_update_cleanup (FuPlugin *plugin,
|
||||||
|
FwupdInstallFlags flags,
|
||||||
|
FuDevice *device,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
FuPluginData *data = fu_plugin_get_data (plugin);
|
||||||
|
if (data->logind_fd == 0)
|
||||||
|
return TRUE;
|
||||||
|
g_debug ("closed logind fd %i", data->logind_fd);
|
||||||
|
if (!g_close (data->logind_fd, error))
|
||||||
|
return FALSE;
|
||||||
|
data->logind_fd = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
23
plugins/logind/meson.build
Normal file
23
plugins/logind/meson.build
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
cargs = ['-DG_LOG_DOMAIN="FuPluginLogind"']
|
||||||
|
|
||||||
|
shared_module('fu_plugin_logind',
|
||||||
|
fu_hash,
|
||||||
|
sources : [
|
||||||
|
'fu-plugin-logind.c',
|
||||||
|
],
|
||||||
|
include_directories : [
|
||||||
|
root_incdir,
|
||||||
|
fwupd_incdir,
|
||||||
|
fwupdplugin_incdir,
|
||||||
|
],
|
||||||
|
install : true,
|
||||||
|
install_dir: plugin_dir,
|
||||||
|
link_with : [
|
||||||
|
fwupd,
|
||||||
|
fwupdplugin,
|
||||||
|
],
|
||||||
|
c_args : cargs,
|
||||||
|
dependencies : [
|
||||||
|
plugin_deps,
|
||||||
|
],
|
||||||
|
)
|
@ -27,6 +27,10 @@ subdir('thelio-io')
|
|||||||
subdir('wacom-raw')
|
subdir('wacom-raw')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
if get_option('systemd')
|
||||||
|
subdir('logind')
|
||||||
|
endif
|
||||||
|
|
||||||
# depends on dfu
|
# depends on dfu
|
||||||
subdir('csr')
|
subdir('csr')
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user