You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
8.1 KiB
189 lines
8.1 KiB
From 795ac6b8b40cd882235adeed4c83356d1ca79f61 Mon Sep 17 00:00:00 2001
|
|
From: Adam Williamson <awilliam@redhat.com>
|
|
Date: Fri, 1 Sep 2023 17:09:16 -0700
|
|
Subject: [PATCH] profiledefaults: don't automatically suspend by default if
|
|
running in a virtual machine
|
|
|
|
To avoid hangs in virtual environments which don't suppport suspension.
|
|
https://invent.kde.org/plasma/powerdevil/-/merge_requests/230
|
|
from Natalie Clarius, rebased on 5.27.7.
|
|
|
|
Signed-off-by: Adam Williamson <awilliam@redhat.com>
|
|
---
|
|
daemon/powerdevilcore.cpp | 4 +++-
|
|
daemon/powerdevilpowermanagement.cpp | 17 +++++++++++++++++
|
|
daemon/powerdevilpowermanagement.h | 1 +
|
|
daemon/powerdevilprofilegenerator.cpp | 17 ++++++++++-------
|
|
daemon/powerdevilprofilegenerator.h | 2 +-
|
|
kcmodule/profiles/EditPage.cpp | 2 ++
|
|
6 files changed, 34 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/daemon/powerdevilcore.cpp b/daemon/powerdevilcore.cpp
|
|
index 0791552c..5c4f8a7d 100644
|
|
--- a/daemon/powerdevilcore.cpp
|
|
+++ b/daemon/powerdevilcore.cpp
|
|
@@ -24,6 +24,7 @@
|
|
#include "powerdevilaction.h"
|
|
#include "powerdevilactionpool.h"
|
|
#include "powerdevilpolicyagent.h"
|
|
+#include "powerdevilpowermanagement.h"
|
|
#include "powerdevilprofilegenerator.h"
|
|
#include "powerdevil_debug.h"
|
|
|
|
@@ -126,8 +127,9 @@ void Core::onBackendReady()
|
|
|
|
// These are generated profiles,
|
|
const bool mobile = Kirigami::TabletModeWatcher::self()->isTabletMode();
|
|
+ const bool vm = PowerDevil::PowerManagement::instance()->isVirtualMachine();
|
|
|
|
- ProfileGenerator::generateProfiles(mobile, toRam, toDisk);
|
|
+ ProfileGenerator::generateProfiles(mobile, vm, toRam, toDisk);
|
|
m_profilesConfig->reparseConfiguration();
|
|
}
|
|
|
|
diff --git a/daemon/powerdevilpowermanagement.cpp b/daemon/powerdevilpowermanagement.cpp
|
|
index 7b8e8d5d..ca4c9f07 100644
|
|
--- a/daemon/powerdevilpowermanagement.cpp
|
|
+++ b/daemon/powerdevilpowermanagement.cpp
|
|
@@ -19,6 +19,7 @@ License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
*********************************************************************/
|
|
|
|
#include "powerdevilpowermanagement.h"
|
|
+#include "powerdevil_debug.h"
|
|
|
|
#include <QDBusConnection>
|
|
#include <QDBusConnectionInterface>
|
|
@@ -217,6 +218,22 @@ void PowerManagement::suspendThenHibernate()
|
|
QDBusConnection::sessionBus().asyncCall(message);
|
|
}
|
|
|
|
+bool PowerManagement::isVirtualMachine()
|
|
+{
|
|
+ QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.systemd1"),
|
|
+ QStringLiteral("/org/freedesktop/systemd1"),
|
|
+ QStringLiteral("org.freedesktop.DBus.Properties"),
|
|
+ QStringLiteral("Get"));
|
|
+ message.setArguments({QStringLiteral("org.freedesktop.systemd1.Manager"), QStringLiteral("Virtualization")});
|
|
+ QDBusReply<QDBusVariant> reply = QDBusConnection::systemBus().call(message);
|
|
+ if (!reply.isValid() || reply.value().variant().isNull() || reply.value().variant().toString().isNull()) {
|
|
+ qCWarning(POWERDEVIL) << "Failed to get property Virtualization from systemd1 DBus service:" << reply.error().message();
|
|
+ return false;
|
|
+ }
|
|
+ /* on bare-metal hardware this is the empty string, otherwise an identifier such as "kvm", "vmware", etc. */
|
|
+ return !reply.value().variant().toString().isEmpty();
|
|
+}
|
|
+
|
|
bool PowerManagement::canSuspend() const
|
|
{
|
|
return d->canSuspend;
|
|
diff --git a/daemon/powerdevilpowermanagement.h b/daemon/powerdevilpowermanagement.h
|
|
index 84c99f19..14069708 100644
|
|
--- a/daemon/powerdevilpowermanagement.h
|
|
+++ b/daemon/powerdevilpowermanagement.h
|
|
@@ -35,6 +35,7 @@ class Q_DECL_EXPORT PowerManagement : public QObject
|
|
public:
|
|
~PowerManagement() override;
|
|
|
|
+ bool isVirtualMachine();
|
|
bool canSuspend() const;
|
|
bool canHibernate() const;
|
|
bool canHybridSuspend() const;
|
|
diff --git a/daemon/powerdevilprofilegenerator.cpp b/daemon/powerdevilprofilegenerator.cpp
|
|
index b3029e02..475b9ed6 100644
|
|
--- a/daemon/powerdevilprofilegenerator.cpp
|
|
+++ b/daemon/powerdevilprofilegenerator.cpp
|
|
@@ -29,7 +29,7 @@
|
|
|
|
namespace PowerDevil {
|
|
|
|
-void ProfileGenerator::generateProfiles(bool mobile, bool toRam, bool toDisk)
|
|
+void ProfileGenerator::generateProfiles(bool mobile, bool vm, bool toRam, bool toDisk)
|
|
{
|
|
// Change critical action if default (hibernate) is unavailable
|
|
if (!toDisk) {
|
|
@@ -64,14 +64,17 @@ void ProfileGenerator::generateProfiles(bool mobile, bool toRam, bool toDisk)
|
|
dimDisplay.writeEntry< int >("idleTime", 300000);
|
|
}
|
|
|
|
- auto initLid = [toRam, mobile](KConfigGroup &profile)
|
|
+ auto initLid = [vm, toRam, mobile](KConfigGroup &profile)
|
|
{
|
|
const Modes defaultPowerButtonAction = mobile ? ToggleScreenOnOffMode : LogoutDialogMode;
|
|
|
|
KConfigGroup handleButtonEvents(&profile, "HandleButtonEvents");
|
|
handleButtonEvents.writeEntry< uint >("powerButtonAction", defaultPowerButtonAction);
|
|
handleButtonEvents.writeEntry< uint >("powerDownAction", LogoutDialogMode);
|
|
- if (toRam) {
|
|
+ if (vm) {
|
|
+ handleButtonEvents.writeEntry< uint >("lidAction", NoneMode);
|
|
+ }
|
|
+ else if (toRam) {
|
|
handleButtonEvents.writeEntry< uint >("lidAction", ToRamMode);
|
|
} else {
|
|
handleButtonEvents.writeEntry< uint >("lidAction", TurnOffScreenMode);
|
|
@@ -91,8 +94,8 @@ void ProfileGenerator::generateProfiles(bool mobile, bool toRam, bool toDisk)
|
|
}
|
|
|
|
// Even on AC power, suspend after a rather long period of inactivity. Energy
|
|
- // is precious!
|
|
- if (toRam) {
|
|
+ // is precious! But not on VMs.
|
|
+ if (toRam && !vm) {
|
|
// on mobile, 7 minutes, on laptop 15 minutes
|
|
auto timeout = mobile ? 420000 : 900000;
|
|
KConfigGroup suspendSession(&acProfile, "SuspendSession");
|
|
@@ -124,7 +127,7 @@ void ProfileGenerator::generateProfiles(bool mobile, bool toRam, bool toDisk)
|
|
}
|
|
|
|
// Last but not least, we want to suspend after some inactivity
|
|
- if (toRam) {
|
|
+ if (toRam && !vm) {
|
|
// on mobile, 5 minute, on laptop 10 minutes
|
|
auto timeout = mobile ? 300000 : 600000;
|
|
KConfigGroup suspendSession(&batteryProfile, "SuspendSession");
|
|
@@ -164,7 +167,7 @@ void ProfileGenerator::generateProfiles(bool mobile, bool toRam, bool toDisk)
|
|
// Last but not least, we want to suspend after a rather long period of inactivity
|
|
// on mobile by default never suspend, if device wants to suspend, it will enable
|
|
// using configuration overlay
|
|
- if (toRam) {
|
|
+ if (toRam && !vm) {
|
|
// config is in the miliseconds
|
|
KConfigGroup suspendSession(&lowBatteryProfile, "SuspendSession");
|
|
suspendSession.writeEntry< uint >("idleTime", 300000);
|
|
diff --git a/daemon/powerdevilprofilegenerator.h b/daemon/powerdevilprofilegenerator.h
|
|
index 481caa73..6f5ffb48 100644
|
|
--- a/daemon/powerdevilprofilegenerator.h
|
|
+++ b/daemon/powerdevilprofilegenerator.h
|
|
@@ -36,7 +36,7 @@ namespace ProfileGenerator
|
|
ToggleScreenOnOffMode = 128
|
|
};
|
|
|
|
- void generateProfiles(bool isMobile, bool toRam, bool toDisk);
|
|
+ void generateProfiles(bool isMobile, bool isVM, bool toRam, bool toDisk);
|
|
}
|
|
|
|
}
|
|
diff --git a/kcmodule/profiles/EditPage.cpp b/kcmodule/profiles/EditPage.cpp
|
|
index 22ed5d0e..119d818e 100644
|
|
--- a/kcmodule/profiles/EditPage.cpp
|
|
+++ b/kcmodule/profiles/EditPage.cpp
|
|
@@ -79,6 +79,7 @@ EditPage::EditPage(QWidget *parent, const QVariantList &args)
|
|
|
|
PowerDevil::ProfileGenerator::generateProfiles(
|
|
interface->isTabletMode(),
|
|
+ PowerDevil::PowerManagement::instance()->isVirtualMachine(),
|
|
PowerDevil::PowerManagement::instance()->canSuspend(),
|
|
PowerDevil::PowerManagement::instance()->canHibernate()
|
|
);
|
|
@@ -198,6 +199,7 @@ void EditPage::restoreDefaultProfiles()
|
|
|
|
PowerDevil::ProfileGenerator::generateProfiles(
|
|
interface->isTabletMode(),
|
|
+ PowerDevil::PowerManagement::instance()->isVirtualMachine(),
|
|
PowerDevil::PowerManagement::instance()->canSuspend(),
|
|
PowerDevil::PowerManagement::instance()->canHibernate()
|
|
);
|
|
--
|
|
2.41.0
|
|
|