diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/power/CMakeLists.txt | 24 | ||||
-rw-r--r-- | src/power/power.c | 187 |
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. |