summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/power/CMakeLists.txt24
-rw-r--r--src/power/power.c187
2 files changed, 143 insertions, 68 deletions
diff --git a/src/power/CMakeLists.txt b/src/power/CMakeLists.txt
index 42e001f..44b2109 100644
--- a/src/power/CMakeLists.txt
+++ b/src/power/CMakeLists.txt
@@ -26,25 +26,25 @@ profile_mof_generate("90_LMI_${PROVIDER_NAME}_Profile.mof.skel" "${TARGET_MOF}"
# Require GLib
pkg_check_modules(GLIB REQUIRED glib-2.0)
+# Try to get Gio
+pkg_check_modules(GIO gio-2.0)
-include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMPI_INCLUDE_DIR} ${GLIB_INCLUDE_DIRS})
-
-target_link_libraries(${LIBRARY_NAME} openlmicommon ${KONKRETCMPI_LIBRARIES} ${GLIB_LIBRARIES})
-
-# Check if we have upower and link it
-pkg_check_modules(UPOWER upower-glib)
-if (${UPOWER_FOUND})
- add_definitions(-DHAS_UPOWER)
- target_link_libraries(${LIBRARY_NAME} ${UPOWER_LIBRARIES})
- include_directories(${UPOWER_INCLUDE_DIRS})
-endif (${UPOWER_FOUND})
+if (${GIO_FOUND})
+ add_definitions("-DHAS_GDBUS")
+ include_directories(${GIO_INCLUDE_DIRS})
+ target_link_libraries(${LIBRARY_NAME} ${GIO_LIBRARIES})
+endif (${GIO_FOUND})
# Check if we have systemctl
find_program(SYSTEMCTL NAMES systemctl)
if (${SYSTEMCTL_FOUND})
- add_definitions(-DHAS_SYSTEMCTL)
+ add_definitions("-DHAS_SYSTEMCTL")
endif (${SYSTEMCTL_FOUND})
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMPI_INCLUDE_DIR} ${GLIB_INCLUDE_DIRS})
+
+target_link_libraries(${LIBRARY_NAME} openlmicommon ${KONKRETCMPI_LIBRARIES} ${GLIB_LIBRARIES})
+
# Create registration file
cim_registration(${PROVIDER_NAME} ${LIBRARY_NAME} ${MOF} share/openlmi-providers)
diff --git a/src/power/power.c b/src/power/power.c
index 96960be..2b7e6dc 100644
--- a/src/power/power.c
+++ b/src/power/power.c
@@ -25,21 +25,27 @@
#include <glib.h>
+#ifdef HAS_GDBUS
+# include <gio/gio.h>
+
+# define LOGIND_NAME "org.freedesktop.login1"
+# define LOGIND_PATH "/org/freedesktop/login1"
+# define LOGIND_INTERFACE "org.freedesktop.login1.Manager"
+
+# define Proxy GDBusProxy
+#else
+ // Fake GDBus types
+# define Proxy void
+#endif
+
#include "LMI_AssociatedPowerManagementService.h"
#include "LMI_PowerConcreteJob.h"
#include "globals.h"
-#ifdef HAS_UPOWER
-// TODO: port to logind
-#define UPOWER_ENABLE_DEPRECATED
-#include <upower.h>
-#endif
-
const char *provider_name = "powermanagement";
const ConfigEntry *provider_config_defaults = NULL;
-
struct _Power {
unsigned int instances;
unsigned short requestedPowerState;
@@ -47,9 +53,6 @@ struct _Power {
const CMPIBroker *broker;
CMPI_MUTEX_TYPE mutex;
GList *jobs; // list of PowerStateChangeJob
-#ifdef HAS_UPOWER
- UpClient *up;
-#endif
};
#define MUTEX_LOCK(power) power->broker->xft->lockMutex(power->mutex)
@@ -90,18 +93,11 @@ Power *power_new(const CMPIBroker *_cb, const CMPIContext *ctx)
#if !defined(GLIB_VERSION_2_36)
g_type_init();
#endif
-#ifdef HAS_UPOWER
- power->up = up_client_new();
-#endif
return power;
}
void power_destroy(Power *power)
{
-#ifdef HAS_UPOWER
- g_object_unref(power->up);
- power->up = NULL;
-#endif
}
Power *power_ref(const CMPIBroker *_cb, const CMPIContext *ctx)
@@ -132,6 +128,72 @@ void power_unref(Power *power)
}
}
+Proxy *power_create_logind()
+{
+#ifdef HAS_GDBUS
+ GError *err = NULL;
+ GDBusProxy *logind_proxy;
+ if ((logind_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE, NULL, LOGIND_NAME, LOGIND_PATH,
+ LOGIND_INTERFACE, NULL, &err)) == NULL) {
+
+ error("Unable to connect to logind via DBus: %s", err->message);
+ g_error_free(err);
+ }
+ return logind_proxy;
+#else
+ return NULL;
+#endif
+}
+
+bool power_call_logind(Proxy *proxy, const char *method)
+{
+#ifdef HAS_GDBUS
+ GVariant *result;
+ GError *err = NULL;
+ if (proxy != NULL) {
+ if ((result = g_dbus_proxy_call_sync(proxy, method,
+ g_variant_new("(b)", false), G_DBUS_CALL_FLAGS_NONE, -1, NULL,
+ &err)) == NULL) {
+
+ error("Unable to call: %s", method, err->message);
+ g_error_free(err);
+ return false;
+ } else {
+ g_variant_unref(result);
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
+bool power_check_logind(Proxy *proxy, const char *method)
+{
+#ifdef HAS_GDBUS
+ GVariant *result;
+ GError *err = NULL;
+ if (proxy != NULL) {
+ if ((result = g_dbus_proxy_call_sync(proxy, method, g_variant_new("()"),
+ G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err)) == NULL) {
+
+ error("Unable to call %s: %s", method, err->message);
+ g_error_free(err);
+ return false;
+ } else {
+ const char *r = g_variant_get_string(g_variant_get_child_value(result, 0), NULL);
+ if (strcasecmp(r, "yes") == 0) {
+ g_variant_unref(result);
+ return true;
+ }
+ g_variant_unref(result);
+ return true;
+ }
+ }
+#endif
+ return false;
+}
+
unsigned short power_requested_power_state(Power *power)
{
return power->requestedPowerState;
@@ -169,20 +231,18 @@ void *state_change_thread(void *data)
return NULL;
}
+ Proxy *logind_proxy = power_create_logind();
// Execute the job
-#ifdef HAS_UPOWER
- GError *error = NULL;
-#endif
int succeeded = 0;
switch (powerStateChangeJob->requestedPowerState) {
case LMI_AssociatedPowerManagementService_PowerState_Sleep__Deep:
// Sleep
-#ifdef HAS_UPOWER
- succeeded = up_client_suspend_sync(powerStateChangeJob->power->up, NULL, &error);
-#else
- succeeded = system("pm-suspend") == 0;
-#endif
+ succeeded = power_call_logind(logind_proxy, "Suspend");
+
+ if (!succeeded) {
+ succeeded = system("pm-suspend") == 0;
+ }
break;
case LMI_AssociatedPowerManagementService_PowerState_Power_Cycle_Off___Soft:
// Reboot (without shutting down programs)
@@ -194,11 +254,11 @@ void *state_change_thread(void *data)
break;
case LMI_AssociatedPowerManagementService_PowerState_Hibernate_Off___Soft:
// Hibernate
-#ifdef HAS_UPOWER
- succeeded = up_client_hibernate_sync(powerStateChangeJob->power->up, NULL, &error);
-#else
- succeeded = system("pm-hibernate") == 0;
-#endif
+ succeeded = power_call_logind(logind_proxy, "Hibernate");
+
+ if (!succeeded) {
+ succeeded = system("pm-hibernate") == 0;
+ }
break;
case LMI_AssociatedPowerManagementService_PowerState_Off___Soft:
// Poweroff (without shutting down programs)
@@ -210,19 +270,19 @@ void *state_change_thread(void *data)
break;
case LMI_AssociatedPowerManagementService_PowerState_Off___Soft_Graceful:
// Poweroff (shut down programs first)
-#ifdef HAS_SYSTEMCTL
- succeeded = system("systemctl poweroff &") == 0;
-#else
- succeeded = system("shutdown --poweroff now &") == 0;
-#endif
+ succeeded = power_call_logind(logind_proxy, "PowerOff");
+
+ if (!succeeded) {
+ succeeded = system("shutdown --poweroff now &") == 0;
+ }
break;
case LMI_AssociatedPowerManagementService_PowerState_Power_Cycle_Off___Soft_Graceful:
// Reboot (shut down programs first)
-#ifdef HAS_SYSTEMCTL
- succeeded = system("systemctl reboot &") == 0;
-#else
- succeeded = system("shutdown --reboot now &") == 0;
-#endif
+ succeeded = power_call_logind(logind_proxy, "Reboot");
+
+ if (!succeeded) {
+ succeeded = system("shutdown --reboot now &") == 0;
+ }
break;
}
@@ -324,6 +384,21 @@ unsigned short *power_available_requested_power_states(Power *power, int *count)
}
int i = 0;
+#ifdef HAS_GDBUS
+ GError *err = NULL;
+ GDBusProxy *logind_proxy;
+ if ((logind_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE, NULL, LOGIND_NAME, LOGIND_PATH,
+ LOGIND_INTERFACE, NULL, &err)) == NULL) {
+
+ error("Unable to connect to logind via DBus: %s", err->message);
+ g_error_free(err);
+ }
+#else
+ void *logind_proxy = NULL;
+#endif
+
+
/* 1 Other
* LMI_AssociatedPowerManagementService_PowerState_Other
*/
@@ -354,15 +429,15 @@ unsigned short *power_available_requested_power_states(Power *power, int *count)
* LMI_AssociatedPowerManagementService_PowerState_Sleep__Deep
*/
// Sleep
-#ifdef HAS_UPOWER
- if (up_client_get_can_suspend(power->up)) {
- list[i++] = LMI_AssociatedPowerManagementService_PowerState_Sleep__Deep;
- }
-#else
- if (system("pm-is-supported --suspend") == 0) {
- list[i++] = LMI_AssociatedPowerManagementService_PowerState_Sleep__Deep;
+ if (logind_proxy) {
+ if (power_check_logind(logind_proxy, "CanSuspend")) {
+ list[i++] = LMI_AssociatedPowerManagementService_PowerState_Sleep__Deep;
+ }
+ } else {
+ if (system("pm-is-supported --suspend") == 0) {
+ list[i++] = LMI_AssociatedPowerManagementService_PowerState_Sleep__Deep;
+ }
}
-#endif
/* 5 Power Cycle (Off - Soft)
* corresponding to ACPI state G2, S5, or D3, but where the managed
@@ -394,15 +469,15 @@ unsigned short *power_available_requested_power_states(Power *power, int *count)
* LMI_AssociatedPowerManagementService_PowerState_Hibernate_Off___Soft
*/
// Hibernate
-#ifdef HAS_UPOWER
- if (up_client_get_can_hibernate(power->up)) {
- list[i++] = LMI_AssociatedPowerManagementService_PowerState_Hibernate_Off___Soft;
- }
-#else
- if (system("pm-is-supported --hibernate") == 0) {
- list[i++] = LMI_AssociatedPowerManagementService_PowerState_Hibernate_Off___Soft;
+ if (logind_proxy) {
+ if (power_check_logind(logind_proxy, "CanHibernate")) {
+ list[i++] = LMI_AssociatedPowerManagementService_PowerState_Hibernate_Off___Soft;
+ }
+ } else {
+ if (system("pm-is-supported --hibernate") == 0) {
+ list[i++] = LMI_AssociatedPowerManagementService_PowerState_Hibernate_Off___Soft;
+ }
}
-#endif
/* 8 Off - Soft
* corresponding to ACPI state G2, S5, or D3.