diff options
Diffstat (limited to 'src')
108 files changed, 1627 insertions, 401 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a9dc85d..589c845 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,9 +1,11 @@ -include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMPI_INCLUDE_DIR}) +include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMPI_INCLUDE_DIR} ${GLIB_INCLUDE_DIRS}) add_library(openlmicommon SHARED openlmi.c ) +target_link_libraries(openlmicommon ${GLIB_LIBRARIES}) + set(OPENLMICOMMON_VERSION_MAJOR 0) set(OPENLMICOMMON_VERSION_MINOR 0) set(OPENLMICOMMON_VERSION_PATCH 1) @@ -16,6 +18,7 @@ install(TARGETS openlmicommon DESTINATION lib${LIB_SUFFIX}) install(FILES openlmi.h DESTINATION include/openlmi) configure_file(openlmi.pc.in openlmi.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/openlmi.pc DESTINATION lib${LIB_SUFFIX}/pkgconfig) +install(FILES openlmi.conf DESTINATION ${SYSCONF_INSTALL_DIR}/openlmi) if (WITH-FAN) add_subdirectory(fan) diff --git a/src/account/CMakeLists.txt b/src/account/CMakeLists.txt index a993094..021b5f2 100644 --- a/src/account/CMakeLists.txt +++ b/src/account/CMakeLists.txt @@ -41,8 +41,7 @@ endforeach(CIM_CLASS ${CIM_CLASSES}) set(TARGET_MOF "${CMAKE_BINARY_DIR}/mof/90_LMI_Account_Profile.mof") profile_mof_generate("90_LMI_Account_Profile.mof.skel" "${TARGET_MOF}" "${CIM_PROVIDERS_CLASSES}") -# Require GLib-2.0 and libuser -pkg_check_modules(GLIB REQUIRED glib-2.0) +# Require libuser pkg_check_modules(LIBUSER REQUIRED libuser) include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMPI_INCLUDE_DIR} ${GLIB_INCLUDE_DIRS} ${LIBUSER_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/src/indmanager) diff --git a/src/account/LMI_AccountCapabilitiesProvider.c b/src/account/LMI_AccountCapabilitiesProvider.c index c950b3a..9526bcc 100644 --- a/src/account/LMI_AccountCapabilitiesProvider.c +++ b/src/account/LMI_AccountCapabilitiesProvider.c @@ -26,6 +26,7 @@ #include "macros.h" #include "globals.h" #include "aux_lu.h" +#include "account_globals.h" #include <libuser/entity.h> #include <libuser/user.h> @@ -36,6 +37,7 @@ static const CMPIBroker* _cb; static void LMI_AccountCapabilitiesInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_AccountCapabilitiesCleanup( diff --git a/src/account/LMI_AccountInstanceCreationIndicationProvider.c b/src/account/LMI_AccountInstanceCreationIndicationProvider.c index a3e149a..7bba103 100644 --- a/src/account/LMI_AccountInstanceCreationIndicationProvider.c +++ b/src/account/LMI_AccountInstanceCreationIndicationProvider.c @@ -25,6 +25,8 @@ #include "indication_common.h" #include "macros.h" +#include "account_globals.h" +#include "openlmi.h" static const CMPIBroker* _cb = NULL; @@ -33,6 +35,7 @@ static IMError im_err = IM_ERR_OK; static void LMI_AccountInstanceCreationIndicationInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); im = im_create_manager(NULL, filter_checker, true, watcher, IM_IND_CREATION, _cb, &im_err); } diff --git a/src/account/LMI_AccountInstanceDeletionIndicationProvider.c b/src/account/LMI_AccountInstanceDeletionIndicationProvider.c index 0e17cc1..ae6e4e3 100644 --- a/src/account/LMI_AccountInstanceDeletionIndicationProvider.c +++ b/src/account/LMI_AccountInstanceDeletionIndicationProvider.c @@ -28,6 +28,8 @@ #include "indication_common.h" #include "macros.h" +#include "account_globals.h" +#include "openlmi.h" static const CMPIBroker* _cb = NULL; @@ -36,6 +38,7 @@ static IMError im_err = IM_ERR_OK; static void LMI_AccountInstanceDeletionIndicationInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); im = im_create_manager(NULL, filter_checker, true, watcher, IM_IND_DELETION, _cb, &im_err); } diff --git a/src/account/LMI_AccountManagementCapabilitiesProvider.c b/src/account/LMI_AccountManagementCapabilitiesProvider.c index 85eef0f..445b5ea 100644 --- a/src/account/LMI_AccountManagementCapabilitiesProvider.c +++ b/src/account/LMI_AccountManagementCapabilitiesProvider.c @@ -33,6 +33,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_AccountManagementCapabilitiesInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_AccountManagementCapabilitiesCleanup( diff --git a/src/account/LMI_AccountManagementServiceCapabilitiesProvider.c b/src/account/LMI_AccountManagementServiceCapabilitiesProvider.c index febc4f3..faa0dd8 100644 --- a/src/account/LMI_AccountManagementServiceCapabilitiesProvider.c +++ b/src/account/LMI_AccountManagementServiceCapabilitiesProvider.c @@ -24,12 +24,14 @@ #include "LMI_AccountManagementCapabilities.h" #include "macros.h" +#include "account_globals.h" #include "globals.h" static const CMPIBroker* _cb; static void LMI_AccountManagementServiceCapabilitiesInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_AccountManagementServiceCapabilitiesCleanup( diff --git a/src/account/LMI_AccountManagementServiceProvider.c b/src/account/LMI_AccountManagementServiceProvider.c index 37cd775..3aac63d 100644 --- a/src/account/LMI_AccountManagementServiceProvider.c +++ b/src/account/LMI_AccountManagementServiceProvider.c @@ -30,6 +30,7 @@ #include "globals.h" #include "aux_lu.h" +#include "account_globals.h" #include <libuser/entity.h> #include <libuser/user.h> @@ -51,6 +52,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_AccountManagementServiceInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_AccountManagementServiceCleanup( @@ -350,6 +352,7 @@ KUint32 LMI_AccountManagementService_CreateAccount( const KBoolean* SystemAccount, const KString* Password, const KBoolean* DontCreateGroup, + const KBoolean* PasswordIsPlain, KRef* Account, KRefA* Identities, CMPIStatus* status) @@ -513,7 +516,13 @@ KUint32 LMI_AccountManagementService_CreateAccount( /* Setup password */ if (Password->exists && !Password->null) { - if (!lu_user_setpass(luc, lue, Password->chars, TRUE, &error)) + bool isplain = TRUE; + if (PasswordIsPlain->exists && !PasswordIsPlain->null && + PasswordIsPlain->value) + { + isplain = FALSE; + } + if (!lu_user_setpass(luc, lue, Password->chars, isplain, &error)) { FAIL("Error setting password: %s\n", lu_strerror(error), OK, RET_ACC_PWD); diff --git a/src/account/LMI_AccountManagementServiceSettingDataProvider.c b/src/account/LMI_AccountManagementServiceSettingDataProvider.c index 89ae650..00131a3 100644 --- a/src/account/LMI_AccountManagementServiceSettingDataProvider.c +++ b/src/account/LMI_AccountManagementServiceSettingDataProvider.c @@ -21,10 +21,13 @@ #include <konkret/konkret.h> #include "LMI_AccountManagementServiceSettingData.h" +#include "account_globals.h" + static const CMPIBroker* _cb; static void LMI_AccountManagementServiceSettingDataInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_AccountManagementServiceSettingDataCleanup( diff --git a/src/account/LMI_AccountOnSystemProvider.c b/src/account/LMI_AccountOnSystemProvider.c index dd03bae..e78763d 100644 --- a/src/account/LMI_AccountOnSystemProvider.c +++ b/src/account/LMI_AccountOnSystemProvider.c @@ -30,12 +30,14 @@ #include "aux_lu.h" #include "macros.h" +#include "account_globals.h" #include "globals.h" static const CMPIBroker* _cb; static void LMI_AccountOnSystemInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_AccountOnSystemCleanup( diff --git a/src/account/LMI_AccountProvider.c b/src/account/LMI_AccountProvider.c index 5805f5e..d8e279a 100644 --- a/src/account/LMI_AccountProvider.c +++ b/src/account/LMI_AccountProvider.c @@ -44,6 +44,7 @@ #include "macros.h" #include "globals.h" #include "lock.h" +#include "account_globals.h" // Return values of functions // Delete user @@ -51,13 +52,18 @@ #define CANNOT_DELETE_HOME 4097 #define CANNOT_DELETE_USER 4098 #define CANNOT_DELETE_GROUP 4099 +// Change password +#define CHANGE_PASSWORD_OK 0 +#define CHANGE_PASSWORD_FAIL 1 static const CMPIBroker* _cb = NULL; static void LMI_AccountInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); if (init_lock_pool() == 0) { - CMReturn(CMPI_RC_ERR_FAILED); + error("Unable to initialize lock pool."); + exit (1); } } @@ -687,6 +693,60 @@ KUint32 LMI_Account_RequestStateChange( return result; } +KUint32 LMI_Account_ChangePassword( + const CMPIBroker* cb, + CMPIMethodMI* mi, + const CMPIContext* context, + const LMI_AccountRef* self, + const KString* Password, + CMPIStatus* status) +{ + struct lu_context *luc = NULL; + struct lu_error *error = NULL; + struct lu_ent *lue = NULL; + char *errmsg = NULL; + KUint32 result = KUINT32_INIT; + KUint32_Set(&result, CHANGE_PASSWORD_OK); + + if(!(Password->exists && !Password->null)) { + asprintf(&errmsg, "Password parameter has to be set"); + KUint32_Set(&result, CHANGE_PASSWORD_FAIL); + CMSetStatusWithChars(_cb, status, CMPI_RC_ERR_FAILED, errmsg); + goto clean; + } + + luc = lu_start(NULL, lu_user, NULL, NULL, lu_prompt_console_quiet, NULL, + &error); + if (!luc) { + asprintf(&errmsg, "Error initializing: %s\n", lu_strerror(error)); + KUint32_Set(&result, CHANGE_PASSWORD_FAIL); + CMSetStatusWithChars(_cb, status, CMPI_RC_ERR_FAILED, errmsg); + goto clean; + } + + lue = lu_ent_new(); + + if (!lu_user_lookup_name(luc, self->Name.chars, lue, &error)) { + asprintf(&errmsg, "Non existing user: %s\n", self->Name.chars); + KUint32_Set(&result, CHANGE_PASSWORD_FAIL); + CMSetStatusWithChars(_cb, status, CMPI_RC_ERR_FAILED, errmsg); + goto clean; + } + + if (!lu_user_setpass(luc, lue, Password->chars, FALSE, &error)) { + asprintf(&errmsg, "Cannot change password: %s\n", lu_strerror(error)); + KUint32_Set(&result, CHANGE_PASSWORD_FAIL); + CMSetStatusWithChars(_cb, status, CMPI_RC_ERR_FAILED, errmsg); + goto clean; + } + +clean: + free(errmsg); + if(luc) lu_end(luc); + if(lue) lu_ent_free(lue); + return result; +} + KUint32 LMI_Account_DeleteUser( const CMPIBroker* cb, diff --git a/src/account/LMI_AccountSettingDataProvider.c b/src/account/LMI_AccountSettingDataProvider.c index 4c51cee..4061db8 100644 --- a/src/account/LMI_AccountSettingDataProvider.c +++ b/src/account/LMI_AccountSettingDataProvider.c @@ -22,6 +22,7 @@ #include "LMI_AccountSettingData.h" #include "macros.h" +#include "account_globals.h" #include "globals.h" #include <libuser/config.h> @@ -31,6 +32,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_AccountSettingDataInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_AccountSettingDataCleanup( diff --git a/src/account/LMI_AssignedAccountIdentityProvider.c b/src/account/LMI_AssignedAccountIdentityProvider.c index e4cd879..9a9c272 100644 --- a/src/account/LMI_AssignedAccountIdentityProvider.c +++ b/src/account/LMI_AssignedAccountIdentityProvider.c @@ -25,6 +25,7 @@ #include "aux_lu.h" #include "macros.h" +#include "account_globals.h" #include "globals.h" #include <libuser/entity.h> @@ -34,6 +35,7 @@ static const CMPIBroker* _cb; static void LMI_AssignedAccountIdentityInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_AssignedAccountIdentityCleanup( diff --git a/src/account/LMI_AssignedGroupIdentityProvider.c b/src/account/LMI_AssignedGroupIdentityProvider.c index d25d276..d406b3c 100644 --- a/src/account/LMI_AssignedGroupIdentityProvider.c +++ b/src/account/LMI_AssignedGroupIdentityProvider.c @@ -25,6 +25,7 @@ #include "aux_lu.h" #include "macros.h" +#include "account_globals.h" #include "globals.h" #include <libuser/entity.h> @@ -34,6 +35,7 @@ static const CMPIBroker* _cb; static void LMI_AssignedGroupIdentityInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_AssignedGroupIdentityCleanup( diff --git a/src/account/LMI_EnabledAccountCapabilitiesProvider.c b/src/account/LMI_EnabledAccountCapabilitiesProvider.c index 014247a..e014024 100644 --- a/src/account/LMI_EnabledAccountCapabilitiesProvider.c +++ b/src/account/LMI_EnabledAccountCapabilitiesProvider.c @@ -22,6 +22,7 @@ #include "LMI_EnabledAccountCapabilities.h" #include "macros.h" +#include "account_globals.h" #include "globals.h" #include <stdbool.h> @@ -30,6 +31,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_EnabledAccountCapabilitiesInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_EnabledAccountCapabilitiesCleanup( diff --git a/src/account/LMI_GroupProvider.c b/src/account/LMI_GroupProvider.c index 0dd548d..6e64c21 100644 --- a/src/account/LMI_GroupProvider.c +++ b/src/account/LMI_GroupProvider.c @@ -26,12 +26,14 @@ #include "aux_lu.h" #include "macros.h" +#include "account_globals.h" #include "globals.h" static const CMPIBroker* _cb = NULL; static void LMI_GroupInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_GroupCleanup( diff --git a/src/account/LMI_HostedAccountManagementServiceProvider.c b/src/account/LMI_HostedAccountManagementServiceProvider.c index dd03a5f..b605f87 100644 --- a/src/account/LMI_HostedAccountManagementServiceProvider.c +++ b/src/account/LMI_HostedAccountManagementServiceProvider.c @@ -24,12 +24,14 @@ #include "LMI_AccountManagementService.h" #include "macros.h" +#include "account_globals.h" #include "globals.h" static const CMPIBroker* _cb; static void LMI_HostedAccountManagementServiceInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_HostedAccountManagementServiceCleanup( diff --git a/src/account/LMI_IdentityProvider.c b/src/account/LMI_IdentityProvider.c index fe6ebb2..a86a5f7 100644 --- a/src/account/LMI_IdentityProvider.c +++ b/src/account/LMI_IdentityProvider.c @@ -27,11 +27,13 @@ #include "macros.h" #include "globals.h" #include "aux_lu.h" +#include "account_globals.h" static const CMPIBroker* _cb = NULL; static void LMI_IdentityInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_IdentityCleanup( diff --git a/src/account/LMI_MemberOfGroupProvider.c b/src/account/LMI_MemberOfGroupProvider.c index 0ea9160..4e27def 100644 --- a/src/account/LMI_MemberOfGroupProvider.c +++ b/src/account/LMI_MemberOfGroupProvider.c @@ -26,6 +26,7 @@ #include "aux_lu.h" #include "macros.h" +#include "account_globals.h" #include "globals.h" #include <libuser/entity.h> @@ -35,6 +36,7 @@ static const CMPIBroker* _cb; static void LMI_MemberOfGroupInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_MemberOfGroupCleanup( diff --git a/src/account/LMI_OwningGroupProvider.c b/src/account/LMI_OwningGroupProvider.c index 23f4a42..a7506f8 100644 --- a/src/account/LMI_OwningGroupProvider.c +++ b/src/account/LMI_OwningGroupProvider.c @@ -26,6 +26,7 @@ #include "macros.h" #include "globals.h" #include "aux_lu.h" +#include "account_globals.h" #include <libuser/user.h> #include <libuser/entity.h> @@ -34,6 +35,7 @@ static const CMPIBroker* _cb; static void LMI_OwningGroupInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_OwningGroupCleanup( diff --git a/src/account/LMI_ServiceAffectsIdentityProvider.c b/src/account/LMI_ServiceAffectsIdentityProvider.c index 5e39a37..8b46ebd 100644 --- a/src/account/LMI_ServiceAffectsIdentityProvider.c +++ b/src/account/LMI_ServiceAffectsIdentityProvider.c @@ -26,6 +26,7 @@ #include "macros.h" #include "globals.h" #include "aux_lu.h" +#include "account_globals.h" #include <libuser/entity.h> #include <libuser/user.h> @@ -34,6 +35,7 @@ static const CMPIBroker* _cb; static void LMI_ServiceAffectsIdentityInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_ServiceAffectsIdentityCleanup( diff --git a/src/account/LMI_SettingsDefineAccountCapabilitiesProvider.c b/src/account/LMI_SettingsDefineAccountCapabilitiesProvider.c index 05e952f..c8f545a 100644 --- a/src/account/LMI_SettingsDefineAccountCapabilitiesProvider.c +++ b/src/account/LMI_SettingsDefineAccountCapabilitiesProvider.c @@ -21,10 +21,13 @@ #include <konkret/konkret.h> #include "LMI_SettingsDefineAccountCapabilities.h" +#include "account_globals.h" + static const CMPIBroker* _cb; static void LMI_SettingsDefineAccountCapabilitiesInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_SettingsDefineAccountCapabilitiesCleanup( diff --git a/src/account/LMI_SettingsDefineManagementCapabilitiesProvider.c b/src/account/LMI_SettingsDefineManagementCapabilitiesProvider.c index c0db7a5..fdfd1f0 100644 --- a/src/account/LMI_SettingsDefineManagementCapabilitiesProvider.c +++ b/src/account/LMI_SettingsDefineManagementCapabilitiesProvider.c @@ -21,10 +21,13 @@ #include <konkret/konkret.h> #include "LMI_SettingsDefineManagementCapabilities.h" +#include "account_globals.h" + static const CMPIBroker* _cb; static void LMI_SettingsDefineManagementCapabilitiesInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_SettingsDefineManagementCapabilitiesCleanup( diff --git a/src/account/account_globals.c b/src/account/account_globals.c index e5e90e0..20146d3 100644 --- a/src/account/account_globals.c +++ b/src/account/account_globals.c @@ -21,4 +21,7 @@ #include "account_globals.h" #include <stddef.h> +const char *provider_name = "account"; +const ConfigEntry *provider_config_defaults = NULL; + const char *crypt_algs[] = {CRYPT_ALGS, NULL}; diff --git a/src/account/account_globals.h b/src/account/account_globals.h index 4226b33..8659e6b 100644 --- a/src/account/account_globals.h +++ b/src/account/account_globals.h @@ -21,6 +21,11 @@ #ifndef ACCOUNT_GLOBALS_H #define ACCOUNT_GLOBALS_H +#include "openlmi.h" + +const char *provider_name; +const ConfigEntry *provider_config_defaults; + /* Global declaration of valid cryptographic algorithms */ extern const char * crypt_algs[]; #endif diff --git a/src/account/lock.c b/src/account/lock.c index cc51190..a12880b 100644 --- a/src/account/lock.c +++ b/src/account/lock.c @@ -180,8 +180,3 @@ int release_lock (const char *const username) RETURN_UNLOCK_CSEC (ret); } - -#undef PREALOCATED_LOCKS_NUM -#undef LOCK_CSEC -#undef UNLOCK_CSEC -#undef RETURN_UNLOCK_CSEC diff --git a/src/fan/LMI_FanAssociatedSensorProvider.c b/src/fan/LMI_FanAssociatedSensorProvider.c index 4253e96..a70adcb 100644 --- a/src/fan/LMI_FanAssociatedSensorProvider.c +++ b/src/fan/LMI_FanAssociatedSensorProvider.c @@ -27,6 +27,7 @@ static const CMPIBroker* _cb; static void LMI_FanAssociatedSensorInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); init_linux_fan_module(); } diff --git a/src/fan/LMI_FanProvider.c b/src/fan/LMI_FanProvider.c index de65deb..2a82551 100644 --- a/src/fan/LMI_FanProvider.c +++ b/src/fan/LMI_FanProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_FanInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); init_linux_fan_module(); } diff --git a/src/fan/LMI_FanSensorProvider.c b/src/fan/LMI_FanSensorProvider.c index 9b9d750..ff459d2 100644 --- a/src/fan/LMI_FanSensorProvider.c +++ b/src/fan/LMI_FanSensorProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_FanSensorInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); init_linux_fan_module(); } diff --git a/src/fan/fan.c b/src/fan/fan.c index 3038503..370572e 100644 --- a/src/fan/fan.c +++ b/src/fan/fan.c @@ -30,6 +30,9 @@ #include "fan.h" #include "globals.h" +const char *provider_name = "fan"; +const ConfigEntry *provider_config_defaults = NULL; + #define MAX_CHIP_NAME_LENGTH 200 //* constants ***************************************************************** diff --git a/src/fan/fan.h b/src/fan/fan.h index 02c6c5c..c0c595b 100644 --- a/src/fan/fan.h +++ b/src/fan/fan.h @@ -22,6 +22,7 @@ #define LINUX_FAN_H_ #include <stdbool.h> +#include "openlmi.h" /** accessible features of fan * each value represents a bit position in accessible_features vector in @@ -38,6 +39,9 @@ #define CIM_FAN_AF_ALARM_MAX (1 << 8) #define CIM_FAN_AF_FEATURE_MAX (1 << 8) +const char *provider_name; +const ConfigEntry *provider_config_defaults; + /** * Descriptions of attributes are taken from: * sysfs-interface documentation of hwmon diff --git a/src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c b/src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c index 6310ea9..57a25c2 100644 --- a/src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c +++ b/src/hardware/LMI_AssociatedProcessorCacheMemoryProvider.c @@ -37,6 +37,7 @@ static const CMPIBroker* _cb; static void LMI_AssociatedProcessorCacheMemoryInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_AssociatedProcessorCacheMemoryCleanup( diff --git a/src/hardware/LMI_BaseboardContainerProvider.c b/src/hardware/LMI_BaseboardContainerProvider.c index 22dee90..eac6f26 100644 --- a/src/hardware/LMI_BaseboardContainerProvider.c +++ b/src/hardware/LMI_BaseboardContainerProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_BaseboardContainerInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_BaseboardContainerCleanup( diff --git a/src/hardware/LMI_BaseboardProvider.c b/src/hardware/LMI_BaseboardProvider.c index f3a7690..627fc8a 100644 --- a/src/hardware/LMI_BaseboardProvider.c +++ b/src/hardware/LMI_BaseboardProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_BaseboardInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_BaseboardCleanup( diff --git a/src/hardware/LMI_BatteryPhysicalPackageProvider.c b/src/hardware/LMI_BatteryPhysicalPackageProvider.c index fbd4888..738e56d 100644 --- a/src/hardware/LMI_BatteryPhysicalPackageProvider.c +++ b/src/hardware/LMI_BatteryPhysicalPackageProvider.c @@ -29,6 +29,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_BatteryPhysicalPackageInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_BatteryPhysicalPackageCleanup( diff --git a/src/hardware/LMI_BatteryProvider.c b/src/hardware/LMI_BatteryProvider.c index f5b8e77..91a1004 100644 --- a/src/hardware/LMI_BatteryProvider.c +++ b/src/hardware/LMI_BatteryProvider.c @@ -30,6 +30,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_BatteryInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_BatteryCleanup( diff --git a/src/hardware/LMI_BatterySystemDeviceProvider.c b/src/hardware/LMI_BatterySystemDeviceProvider.c index 58d59dc..c71de0c 100644 --- a/src/hardware/LMI_BatterySystemDeviceProvider.c +++ b/src/hardware/LMI_BatterySystemDeviceProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_BatterySystemDeviceInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_BatterySystemDeviceCleanup( diff --git a/src/hardware/LMI_ChassisComputerSystemPackageProvider.c b/src/hardware/LMI_ChassisComputerSystemPackageProvider.c index 2f8e082..db188e1 100644 --- a/src/hardware/LMI_ChassisComputerSystemPackageProvider.c +++ b/src/hardware/LMI_ChassisComputerSystemPackageProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_ChassisComputerSystemPackageInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_ChassisComputerSystemPackageCleanup( diff --git a/src/hardware/LMI_ChassisProvider.c b/src/hardware/LMI_ChassisProvider.c index 3214d58..5ab2a39 100644 --- a/src/hardware/LMI_ChassisProvider.c +++ b/src/hardware/LMI_ChassisProvider.c @@ -30,6 +30,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_ChassisInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_ChassisCleanup( diff --git a/src/hardware/LMI_Hardware.h b/src/hardware/LMI_Hardware.h index 7f94055..0ea6237 100644 --- a/src/hardware/LMI_Hardware.h +++ b/src/hardware/LMI_Hardware.h @@ -21,6 +21,11 @@ #ifndef LMI_HARDWARE_H_ #define LMI_HARDWARE_H_ +#include "globals.h" + +const ConfigEntry *provider_config_defaults; +const char *provider_name; + #define INSTANCE_ID_LEN 128 #define ELEMENT_NAME_LEN 128 diff --git a/src/hardware/LMI_MemoryPhysicalPackageInConnectorProvider.c b/src/hardware/LMI_MemoryPhysicalPackageInConnectorProvider.c index 49f543b..50ea529 100644 --- a/src/hardware/LMI_MemoryPhysicalPackageInConnectorProvider.c +++ b/src/hardware/LMI_MemoryPhysicalPackageInConnectorProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_MemoryPhysicalPackageInConnectorInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_MemoryPhysicalPackageInConnectorCleanup( diff --git a/src/hardware/LMI_MemoryPhysicalPackageProvider.c b/src/hardware/LMI_MemoryPhysicalPackageProvider.c index 0e819eb..f86557d 100644 --- a/src/hardware/LMI_MemoryPhysicalPackageProvider.c +++ b/src/hardware/LMI_MemoryPhysicalPackageProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_MemoryPhysicalPackageInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_MemoryPhysicalPackageCleanup( diff --git a/src/hardware/LMI_MemoryProvider.c b/src/hardware/LMI_MemoryProvider.c index 4f2ab7f..f5f9ae8 100644 --- a/src/hardware/LMI_MemoryProvider.c +++ b/src/hardware/LMI_MemoryProvider.c @@ -33,6 +33,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_MemoryInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_MemoryCleanup( diff --git a/src/hardware/LMI_MemorySlotContainerProvider.c b/src/hardware/LMI_MemorySlotContainerProvider.c index 37c7bce..6cc83b4 100644 --- a/src/hardware/LMI_MemorySlotContainerProvider.c +++ b/src/hardware/LMI_MemorySlotContainerProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_MemorySlotContainerInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_MemorySlotContainerCleanup( diff --git a/src/hardware/LMI_MemorySlotProvider.c b/src/hardware/LMI_MemorySlotProvider.c index d76be9a..9c72d15 100644 --- a/src/hardware/LMI_MemorySlotProvider.c +++ b/src/hardware/LMI_MemorySlotProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_MemorySlotInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_MemorySlotCleanup( diff --git a/src/hardware/LMI_MemorySystemDeviceProvider.c b/src/hardware/LMI_MemorySystemDeviceProvider.c index d4d310a..9b25535 100644 --- a/src/hardware/LMI_MemorySystemDeviceProvider.c +++ b/src/hardware/LMI_MemorySystemDeviceProvider.c @@ -27,6 +27,7 @@ static const CMPIBroker* _cb; static void LMI_MemorySystemDeviceInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_MemorySystemDeviceCleanup( diff --git a/src/hardware/LMI_PCIBridgeProvider.c b/src/hardware/LMI_PCIBridgeProvider.c index ed97a7b..e712626 100644 --- a/src/hardware/LMI_PCIBridgeProvider.c +++ b/src/hardware/LMI_PCIBridgeProvider.c @@ -32,6 +32,8 @@ struct pci_access *acc_bridge = NULL; static void LMI_PCIBridgeInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); + if (init_pci_access(&acc_bridge, PCI_FILL_IDENT | PCI_FILL_IRQ | PCI_FILL_BASES diff --git a/src/hardware/LMI_PCIBridgeSystemDeviceProvider.c b/src/hardware/LMI_PCIBridgeSystemDeviceProvider.c index 6f947ab..2532c38 100644 --- a/src/hardware/LMI_PCIBridgeSystemDeviceProvider.c +++ b/src/hardware/LMI_PCIBridgeSystemDeviceProvider.c @@ -30,6 +30,8 @@ struct pci_access *acc_system_bridge = NULL; static void LMI_PCIBridgeSystemDeviceInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); + if (init_pci_access(&acc_system_bridge, PCI_FILL_CLASS) != 0) { error("Failed to access the PCI bus."); abort(); diff --git a/src/hardware/LMI_PCIDeviceProvider.c b/src/hardware/LMI_PCIDeviceProvider.c index e2a159b..1a9eeca 100644 --- a/src/hardware/LMI_PCIDeviceProvider.c +++ b/src/hardware/LMI_PCIDeviceProvider.c @@ -31,6 +31,8 @@ struct pci_access *acc_dev = NULL; static void LMI_PCIDeviceInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); + if (init_pci_access(&acc_dev, PCI_FILL_IDENT | PCI_FILL_IRQ | PCI_FILL_BASES diff --git a/src/hardware/LMI_PCIDeviceSystemDeviceProvider.c b/src/hardware/LMI_PCIDeviceSystemDeviceProvider.c index d7af669..cf8634c 100644 --- a/src/hardware/LMI_PCIDeviceSystemDeviceProvider.c +++ b/src/hardware/LMI_PCIDeviceSystemDeviceProvider.c @@ -30,6 +30,8 @@ struct pci_access *acc_system_dev = NULL; static void LMI_PCIDeviceSystemDeviceInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); + if (init_pci_access(&acc_system_dev, PCI_FILL_CLASS) != 0) { error("Failed to access the PCI bus."); abort(); diff --git a/src/hardware/LMI_PhysicalBatteryContainerProvider.c b/src/hardware/LMI_PhysicalBatteryContainerProvider.c index 890cd93..67acbb7 100644 --- a/src/hardware/LMI_PhysicalBatteryContainerProvider.c +++ b/src/hardware/LMI_PhysicalBatteryContainerProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_PhysicalBatteryContainerInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_PhysicalBatteryContainerCleanup( diff --git a/src/hardware/LMI_PhysicalBatteryRealizesProvider.c b/src/hardware/LMI_PhysicalBatteryRealizesProvider.c index c554fd5..66ab5f7 100644 --- a/src/hardware/LMI_PhysicalBatteryRealizesProvider.c +++ b/src/hardware/LMI_PhysicalBatteryRealizesProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_PhysicalBatteryRealizesInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_PhysicalBatteryRealizesCleanup( diff --git a/src/hardware/LMI_PhysicalMemoryContainerProvider.c b/src/hardware/LMI_PhysicalMemoryContainerProvider.c index 427bef8..57cd994 100644 --- a/src/hardware/LMI_PhysicalMemoryContainerProvider.c +++ b/src/hardware/LMI_PhysicalMemoryContainerProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_PhysicalMemoryContainerInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_PhysicalMemoryContainerCleanup( diff --git a/src/hardware/LMI_PhysicalMemoryProvider.c b/src/hardware/LMI_PhysicalMemoryProvider.c index 51be88f..53d5256 100644 --- a/src/hardware/LMI_PhysicalMemoryProvider.c +++ b/src/hardware/LMI_PhysicalMemoryProvider.c @@ -31,6 +31,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_PhysicalMemoryInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_PhysicalMemoryCleanup( diff --git a/src/hardware/LMI_PhysicalMemoryRealizesProvider.c b/src/hardware/LMI_PhysicalMemoryRealizesProvider.c index 0da8d33..c50e517 100644 --- a/src/hardware/LMI_PhysicalMemoryRealizesProvider.c +++ b/src/hardware/LMI_PhysicalMemoryRealizesProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_PhysicalMemoryRealizesInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_PhysicalMemoryRealizesCleanup( diff --git a/src/hardware/LMI_PointingDeviceProvider.c b/src/hardware/LMI_PointingDeviceProvider.c index d5203d2..5fbecb8 100644 --- a/src/hardware/LMI_PointingDeviceProvider.c +++ b/src/hardware/LMI_PointingDeviceProvider.c @@ -30,6 +30,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_PointingDeviceInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_PointingDeviceCleanup( diff --git a/src/hardware/LMI_PortPhysicalConnectorContainerProvider.c b/src/hardware/LMI_PortPhysicalConnectorContainerProvider.c index d54f678..5b53af3 100644 --- a/src/hardware/LMI_PortPhysicalConnectorContainerProvider.c +++ b/src/hardware/LMI_PortPhysicalConnectorContainerProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_PortPhysicalConnectorContainerInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_PortPhysicalConnectorContainerCleanup( diff --git a/src/hardware/LMI_PortPhysicalConnectorProvider.c b/src/hardware/LMI_PortPhysicalConnectorProvider.c index 4027928..75f6738 100644 --- a/src/hardware/LMI_PortPhysicalConnectorProvider.c +++ b/src/hardware/LMI_PortPhysicalConnectorProvider.c @@ -30,6 +30,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_PortPhysicalConnectorInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_PortPhysicalConnectorCleanup( diff --git a/src/hardware/LMI_ProcessorCacheMemoryProvider.c b/src/hardware/LMI_ProcessorCacheMemoryProvider.c index 2791b95..65c3867 100644 --- a/src/hardware/LMI_ProcessorCacheMemoryProvider.c +++ b/src/hardware/LMI_ProcessorCacheMemoryProvider.c @@ -31,6 +31,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_ProcessorCacheMemoryInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_ProcessorCacheMemoryCleanup( diff --git a/src/hardware/LMI_ProcessorCapabilitiesProvider.c b/src/hardware/LMI_ProcessorCapabilitiesProvider.c index d398523..b3bf7b6 100644 --- a/src/hardware/LMI_ProcessorCapabilitiesProvider.c +++ b/src/hardware/LMI_ProcessorCapabilitiesProvider.c @@ -29,6 +29,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_ProcessorCapabilitiesInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_ProcessorCapabilitiesCleanup( diff --git a/src/hardware/LMI_ProcessorChipContainerProvider.c b/src/hardware/LMI_ProcessorChipContainerProvider.c index b300121..9662380 100644 --- a/src/hardware/LMI_ProcessorChipContainerProvider.c +++ b/src/hardware/LMI_ProcessorChipContainerProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_ProcessorChipContainerInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_ProcessorChipContainerCleanup( diff --git a/src/hardware/LMI_ProcessorChipProvider.c b/src/hardware/LMI_ProcessorChipProvider.c index 1606dce..9949de6 100644 --- a/src/hardware/LMI_ProcessorChipProvider.c +++ b/src/hardware/LMI_ProcessorChipProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_ProcessorChipInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_ProcessorChipCleanup( diff --git a/src/hardware/LMI_ProcessorChipRealizesProvider.c b/src/hardware/LMI_ProcessorChipRealizesProvider.c index 55efba8..6d85c7d 100644 --- a/src/hardware/LMI_ProcessorChipRealizesProvider.c +++ b/src/hardware/LMI_ProcessorChipRealizesProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_ProcessorChipRealizesInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_ProcessorChipRealizesCleanup( diff --git a/src/hardware/LMI_ProcessorElementCapabilitiesProvider.c b/src/hardware/LMI_ProcessorElementCapabilitiesProvider.c index b9b042d..2f25e62 100644 --- a/src/hardware/LMI_ProcessorElementCapabilitiesProvider.c +++ b/src/hardware/LMI_ProcessorElementCapabilitiesProvider.c @@ -31,6 +31,7 @@ static const CMPIBroker* _cb; static void LMI_ProcessorElementCapabilitiesInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_ProcessorElementCapabilitiesCleanup( diff --git a/src/hardware/LMI_ProcessorProvider.c b/src/hardware/LMI_ProcessorProvider.c index 8e1c9f5..fbf1d13 100644 --- a/src/hardware/LMI_ProcessorProvider.c +++ b/src/hardware/LMI_ProcessorProvider.c @@ -40,6 +40,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_ProcessorInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_ProcessorCleanup( diff --git a/src/hardware/LMI_ProcessorSystemDeviceProvider.c b/src/hardware/LMI_ProcessorSystemDeviceProvider.c index 327f711..2b5112a 100644 --- a/src/hardware/LMI_ProcessorSystemDeviceProvider.c +++ b/src/hardware/LMI_ProcessorSystemDeviceProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_ProcessorSystemDeviceInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_ProcessorSystemDeviceCleanup( diff --git a/src/hardware/LMI_SystemSlotContainerProvider.c b/src/hardware/LMI_SystemSlotContainerProvider.c index 7a25254..af39495 100644 --- a/src/hardware/LMI_SystemSlotContainerProvider.c +++ b/src/hardware/LMI_SystemSlotContainerProvider.c @@ -28,6 +28,7 @@ static const CMPIBroker* _cb; static void LMI_SystemSlotContainerInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_SystemSlotContainerCleanup( diff --git a/src/hardware/LMI_SystemSlotProvider.c b/src/hardware/LMI_SystemSlotProvider.c index 3feba71..0de8344 100644 --- a/src/hardware/LMI_SystemSlotProvider.c +++ b/src/hardware/LMI_SystemSlotProvider.c @@ -31,6 +31,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_SystemSlotInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_SystemSlotCleanup( diff --git a/src/hardware/utils.c b/src/hardware/utils.c index c9deda9..20d9fca 100644 --- a/src/hardware/utils.c +++ b/src/hardware/utils.c @@ -20,6 +20,8 @@ #include "utils.h" +const ConfigEntry *provider_config_defaults = NULL; +const char *provider_name = "hardware"; short read_fp_to_2d_buffer(FILE *fp, char ***buffer, unsigned *buffer_size) { diff --git a/src/logicalfile/LMI_DataFileProvider.c b/src/logicalfile/LMI_DataFileProvider.c index ea410c3..fb34b47 100644 --- a/src/logicalfile/LMI_DataFileProvider.c +++ b/src/logicalfile/LMI_DataFileProvider.c @@ -25,6 +25,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_DataFileInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_DataFileCleanup( @@ -61,8 +62,18 @@ static CMPIStatus LMI_DataFileGetInstance( const CMPIObjectPath* cop, const char** properties) { - get_instance(DataFile, S_IFREG, "Not a regular file: %s"); - CMReturn(CMPI_RC_OK); + CMPIStatus st = {.rc = CMPI_RC_OK}; + logicalfile_t logicalfile; + + st = lmi_check_required(_cb, cop); + check_status(st); + + LMI_DataFile_InitFromObjectPath(&logicalfile.lf.datafile, _cb, cop); + st = stat_logicalfile_and_fill(_cb, &logicalfile, S_IFREG, "Not a regular file: %s"); + check_status(st); + + KReturnInstance(cr, logicalfile.lf.datafile); + return st; } static CMPIStatus LMI_DataFileCreateInstance( @@ -145,3 +156,6 @@ KONKRET_REGISTRATION( "LMI_DataFile", "instance method") /* vi: set et: */ +/* Local Variables: */ +/* indent-tabs-mode: nil */ +/* End: */ diff --git a/src/logicalfile/LMI_DirectoryContainsFileProvider.c b/src/logicalfile/LMI_DirectoryContainsFileProvider.c index 753cb00..18eba8b 100644 --- a/src/logicalfile/LMI_DirectoryContainsFileProvider.c +++ b/src/logicalfile/LMI_DirectoryContainsFileProvider.c @@ -90,10 +90,16 @@ static CMPIStatus dir_file_objectpaths( CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, err); } else { get_class_from_stat(&sb, fileclass); - check_assoc_class(_cb, namespace, resultClass, fileclass); - if (get_fsname_from_stat(&sb, &fsname) < 0) { + st = check_assoc_class(_cb, namespace, resultClass, fileclass); + check_class_check_status(st); + if (st.rc != CMPI_RC_OK) { closedir(dp); - CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, "Can't get filesystem name"); + return st; + } + st = get_fsname_from_stat(_cb, &sb, &fsname); + if (st.rc != CMPI_RC_OK) { + closedir(dp); + return st; } } @@ -151,11 +157,12 @@ static CMPIStatus associators( int group = -1; int rgroup = -1; - st = lmi_check_required(_cb, cop, LOGICALFILE); + st = lmi_check_required(_cb, cop); if (st.rc != CMPI_RC_OK) { return st; } - check_assoc_class(_cb, ns, assocClass, LMI_DirectoryContainsFile_ClassName); + st = check_assoc_class(_cb, ns, assocClass, LMI_DirectoryContainsFile_ClassName); + check_class_check_status(st); /* allow only LMI_UnixFile and classes derived from CIM_LogicalFile */ if (!check_valid_classes(cop)) { CMReturn(CMPI_RC_OK); @@ -200,6 +207,8 @@ static CMPIStatus associators( CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, "Too many files in a single directory..."); } + /* TODO: directories are walked in two passes + * rewrite using only one pass */ for (unsigned int i = 0; i < count; i++) { if (names) { CMReturnObjectPath(cr, refs[i]); @@ -210,21 +219,24 @@ static CMPIStatus associators( } } else { /* got LogicalFile - PartComponent */ + if (group == 1 || rgroup == 0) { + CMReturn(CMPI_RC_OK); + } + st = check_assoc_class(_cb, ns, resultClass, LMI_UnixDirectory_ClassName); + check_class_check_status(st); + CIM_DirectoryRef lmi_dr; CIM_DirectoryRef_Init(&lmi_dr, _cb, ns); char *aux = strdup(path); char *dir = dirname(aux); char *fsname; - if (group == 1 || rgroup == 0) { - CMReturn(CMPI_RC_OK); - } - check_assoc_class(_cb, ns, resultClass, LMI_UnixDirectory_ClassName); - - if (get_fsname_from_path(dir, &fsname) < 0) { + st = get_fsname_from_path(_cb, path, &fsname); + if (st.rc != CMPI_RC_OK) { free(aux); - CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, "Can't get filesystem name"); + return st; } + fill_logicalfile(CIM_DirectoryRef, &lmi_dr, dir, fsname, LMI_UnixDirectory_ClassName); o = CIM_DirectoryRef_ToObjectPath(&lmi_dr, &st); CMSetClassName(o, LMI_UnixDirectory_ClassName); @@ -263,7 +275,8 @@ static CMPIStatus references( CMPIInstance *ci; int group = -1; - check_assoc_class(_cb, ns, assocClass, LMI_DirectoryContainsFile_ClassName); + st = check_assoc_class(_cb, ns, assocClass, LMI_DirectoryContainsFile_ClassName); + check_class_check_status(st); /* allow only LMI_UnixFile and classes derived from CIM_LogicalFile */ if (!check_valid_classes(cop)) { CMReturn(CMPI_RC_OK); @@ -277,10 +290,8 @@ static CMPIStatus references( group = 0; } } - st = lmi_check_required(_cb, cop, LOGICALFILE); - if (st.rc != CMPI_RC_OK) { - return st; - } + st = lmi_check_required(_cb, cop); + check_status(st); CIM_DirectoryRef_Init(&lmi_dr, _cb, ns); CIM_LogicalFileRef_Init(&lmi_lfr, _cb, ns); @@ -289,9 +300,8 @@ static CMPIStatus references( const char *ccname = get_string_property_from_op(cop, "CreationClassName"); const char *path = get_string_property_from_op(cop, "Name"); char *fsname; - if (get_fsname_from_path(path, &fsname) < 0) { - CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, "Can't get filesystem name"); - } + st = get_fsname_from_path(_cb, path, &fsname); + check_status(st); if (strcmp(ccname, LMI_UnixDirectory_ClassName) == 0) { /* got GroupComponent - DirectoryRef */ @@ -304,12 +314,12 @@ static CMPIStatus references( CMPIObjectPath *refs[MAX_REFS]; unsigned int count; st = dir_file_objectpaths(cc, cr, NULL, group, -1, properties, ns, path, refs, &count); - if (st.rc != CMPI_RC_OK) { - return st; - } + check_status(st); if (count > MAX_REFS) { CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, "Too many files in a single directory..."); } + /* TODO: directories are walked in two passes + * rewrite using only one pass */ for (unsigned int i = 0; i < count; i++) { LMI_DirectoryContainsFile_SetObjectPath_PartComponent(&lmi_dcf, refs[i]); o = LMI_DirectoryContainsFile_ToObjectPath(&lmi_dcf, &st); @@ -335,9 +345,10 @@ static CMPIStatus references( char *aux = strdup(path); char *dir = dirname(aux); char *fsname; - if (get_fsname_from_path(dir, &fsname) < 0) { + st = get_fsname_from_path(_cb, dir, &fsname); + if (st.rc != CMPI_RC_OK) { free(aux); - CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, "Can't get filesystem name"); + return st; } fill_logicalfile(CIM_DirectoryRef, &lmi_dr, dir, fsname, LMI_UnixDirectory_ClassName); @@ -360,6 +371,7 @@ static CMPIStatus references( static void LMI_DirectoryContainsFileInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_DirectoryContainsFileCleanup( diff --git a/src/logicalfile/LMI_FIFOPipeFileProvider.c b/src/logicalfile/LMI_FIFOPipeFileProvider.c index 8730299..8277e49 100644 --- a/src/logicalfile/LMI_FIFOPipeFileProvider.c +++ b/src/logicalfile/LMI_FIFOPipeFileProvider.c @@ -25,6 +25,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_FIFOPipeFileInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_FIFOPipeFileCleanup( @@ -61,7 +62,19 @@ static CMPIStatus LMI_FIFOPipeFileGetInstance( const CMPIObjectPath* cop, const char** properties) { - get_instance(FIFOPipeFile, S_IFIFO, "No such FIFO: %s"); + CMPIStatus st = {.rc = CMPI_RC_OK}; + logicalfile_t logicalfile; + + st = lmi_check_required(_cb, cop); + check_status(st); + + LMI_FIFOPipeFile_InitFromObjectPath(&logicalfile.lf.fifopipefile, _cb, cop); + st = stat_logicalfile_and_fill(_cb, &logicalfile, S_IFIFO, "No such FIFO: %s"); + check_status(st); + + KReturnInstance(cr, logicalfile.lf.fifopipefile); + return st; + CMReturn(CMPI_RC_OK); } @@ -145,3 +158,6 @@ KONKRET_REGISTRATION( "LMI_FIFOPipeFile", "instance method") /* vi: set et: */ +/* Local Variables: */ +/* indent-tabs-mode: nil */ +/* End: */ diff --git a/src/logicalfile/LMI_FileIdentityProvider.c b/src/logicalfile/LMI_FileIdentityProvider.c index 7ada787..f041c5b 100644 --- a/src/logicalfile/LMI_FileIdentityProvider.c +++ b/src/logicalfile/LMI_FileIdentityProvider.c @@ -68,7 +68,8 @@ static CMPIStatus associators( char fileclass[BUFLEN]; char *fsname; - check_assoc_class(_cb, ns, assocClass, LMI_FileIdentity_ClassName); + st = check_assoc_class(_cb, ns, assocClass, LMI_FileIdentity_ClassName); + check_class_check_status(st); /* allow only LMI_UnixFile and classes derived from CIM_LogicalFile */ if (!check_valid_classes(cop)) { CMReturn(CMPI_RC_OK); @@ -76,7 +77,7 @@ static CMPIStatus associators( if (CMClassPathIsA(_cb, cop, LMI_UnixFile_ClassName, &st)) { /* got UnixFile - SameElement */ - st = lmi_check_required(_cb, cop, UNIXFILE); + st = lmi_check_required(_cb, cop); if (st.rc != CMPI_RC_OK) { return st; } @@ -84,7 +85,8 @@ static CMPIStatus associators( const char *path = get_string_property_from_op(cop, "LFName"); const char *ccname = get_string_property_from_op(cop, "LFCreationClassName"); - check_assoc_class(_cb, ns, resultClass, ccname); + st = check_assoc_class(_cb, ns, resultClass, ccname); + check_class_check_status(st); if (role && strcmp(role, SAME_ELEMENT) != 0) { CMReturn(CMPI_RC_OK); } @@ -93,15 +95,8 @@ static CMPIStatus associators( } get_class_from_path(path, fileclass); - if (get_fsname_from_path(path, &fsname) < 0) { - CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, "Can't get filesystem name"); - } - - /* TODO is this error necessary? */ - if (strcmp(fileclass, ccname) != 0) { - CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, - "LMCreationClassName is not correct"); - } + st = get_fsname_from_path(_cb, path, &fsname); + check_status(st); CIM_LogicalFileRef cim_lfr; CIM_LogicalFileRef_Init(&cim_lfr, _cb, ns); @@ -110,14 +105,15 @@ static CMPIStatus associators( CMSetClassName(o, fileclass); } else { /* got LogicalFile - SystemElement */ - st = lmi_check_required(_cb, cop, LOGICALFILE); + st = lmi_check_required(_cb, cop); if (st.rc != CMPI_RC_OK) { return st; } const char *path = get_string_property_from_op(cop, "Name"); - check_assoc_class(_cb, ns, resultClass, LMI_UnixFile_ClassName); + st = check_assoc_class(_cb, ns, resultClass, LMI_UnixFile_ClassName); + check_class_check_status(st); if (role && strcmp(role, SYSTEM_ELEMENT) != 0) { CMReturn(CMPI_RC_OK); } @@ -126,9 +122,8 @@ static CMPIStatus associators( } get_class_from_path(path, fileclass); - if (get_fsname_from_path(path, &fsname) < 0) { - CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, "Can't get filesystem name"); - } + st = get_fsname_from_path(_cb, path, &fsname); + check_status(st); LMI_UnixFile lmi_uf; LMI_UnixFile_Init(&lmi_uf, _cb, ns); @@ -169,7 +164,8 @@ static CMPIStatus references( char fileclass[BUFLEN]; char *fsname; - check_assoc_class(_cb, ns, assocClass, LMI_FileIdentity_ClassName); + st = check_assoc_class(_cb, ns, assocClass, LMI_FileIdentity_ClassName); + check_class_check_status(st); /* * allow only LMI_UnixFile and classes derived from CIM_LogicalFile * @@ -186,7 +182,7 @@ static CMPIStatus references( /* got UnixFile - SameElement */ LMI_FileIdentity_SetObjectPath_SameElement(&lmi_fi, cop); - st = lmi_check_required(_cb, cop, UNIXFILE); + st = lmi_check_required(_cb, cop); if (st.rc != CMPI_RC_OK) { return st; } @@ -199,9 +195,8 @@ static CMPIStatus references( } get_class_from_path(path, fileclass); - if (get_fsname_from_path(path, &fsname) < 0) { - CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, "Can't get filesystem name"); - } + st = get_fsname_from_path(_cb, path, &fsname); + check_status(st); /* TODO is this error necessary? */ if (strcmp(fileclass, ccname) != 0) { @@ -220,7 +215,7 @@ static CMPIStatus references( /* got LogicalFile - SystemElement */ LMI_FileIdentity_SetObjectPath_SystemElement(&lmi_fi, cop); - st = lmi_check_required(_cb, cop, LOGICALFILE); + st = lmi_check_required(_cb, cop); if (st.rc != CMPI_RC_OK) { return st; } @@ -231,9 +226,8 @@ static CMPIStatus references( if (role && strcmp(role, SYSTEM_ELEMENT) != 0) { CMReturn(CMPI_RC_OK); } - if (get_fsname_from_path(path, &fsname) < 0) { - CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, "Can't get filesystem name"); - } + st = get_fsname_from_path(_cb, path, &fsname); + check_status(st); /* SameElement */ LMI_UnixFile lmi_uf; @@ -261,6 +255,7 @@ static CMPIStatus references( static void LMI_FileIdentityInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_FileIdentityCleanup( diff --git a/src/logicalfile/LMI_RootDirectoryProvider.c b/src/logicalfile/LMI_RootDirectoryProvider.c index 2be709f..9b4ecac 100644 --- a/src/logicalfile/LMI_RootDirectoryProvider.c +++ b/src/logicalfile/LMI_RootDirectoryProvider.c @@ -61,7 +61,8 @@ static CMPIStatus associators( const char *path = get_string_property_from_op(cop, "Name"); char *fsname; - check_assoc_class(_cb, ns, assocClass, LMI_RootDirectory_ClassName); + st = check_assoc_class(_cb, ns, assocClass, LMI_RootDirectory_ClassName); + check_class_check_status(st); /* * allow only LMI_UnixDirectory and Linux_ComputerSystem * XXX @@ -70,13 +71,13 @@ static CMPIStatus associators( CMReturn(CMPI_RC_OK); } - if (get_fsname_from_path("/", &fsname) < 0) { - CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, "Can't get filesystem name"); - } + st = get_fsname_from_path(_cb, "/", &fsname); + check_status(st); if (CMClassPathIsA(_cb, cop, LMI_UnixDirectory_ClassName, &st)) { /* got LMI_UnixDirectory - PartComponent */ - check_assoc_class(_cb, ns, resultClass, comp_ccname); + st = check_assoc_class(_cb, ns, resultClass, comp_ccname); + check_class_check_status(st); if (role && strcmp(role, PART_COMPONENT) != 0) { CMReturn(CMPI_RC_OK); } @@ -102,7 +103,8 @@ static CMPIStatus associators( } } else { /* got Linux_ComputerSystem - GroupComponent */ - check_assoc_class(_cb, ns, resultClass, LMI_UnixDirectory_ClassName); + st = check_assoc_class(_cb, ns, resultClass, LMI_UnixDirectory_ClassName); + check_class_check_status(st); if (role && strcmp(role, GROUP_COMPONENT) != 0) { CMReturn(CMPI_RC_OK); } @@ -144,7 +146,8 @@ static CMPIStatus references( const char *path = get_string_property_from_op(cop, "Name"); const char *ccname = get_string_property_from_op(cop, "CreationClassName"); - check_assoc_class(_cb, ns, assocClass, LMI_RootDirectory_ClassName); + st = check_assoc_class(_cb, ns, assocClass, LMI_RootDirectory_ClassName); + check_class_check_status(st); /* * allow only LMI_UnixDirectory and Linux_ComputerSystem * XXX @@ -154,9 +157,8 @@ static CMPIStatus references( } char *fsname; - if (get_fsname_from_path("/", &fsname) < 0) { - CMReturnWithChars(_cb, CMPI_RC_ERR_FAILED, "Can't get filesystem name"); - } + st = get_fsname_from_path(_cb, "/", &fsname); + check_status(st); LMI_RootDirectory_Init(&lmi_rd, _cb, ns); @@ -169,10 +171,8 @@ static CMPIStatus references( if (strcmp(path, "/") != 0) { CMReturn(CMPI_RC_OK); } - st = lmi_check_required(_cb, cop, LOGICALFILE); - if (st.rc != CMPI_RC_OK) { - return st; - } + st = lmi_check_required(_cb, cop); + check_status(st); LMI_RootDirectory_SetObjectPath_PartComponent(&lmi_rd, cop); CIM_ComputerSystemRef cim_csr; @@ -209,6 +209,7 @@ static CMPIStatus references( static void LMI_RootDirectoryInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_RootDirectoryCleanup( diff --git a/src/logicalfile/LMI_SymbolicLinkProvider.c b/src/logicalfile/LMI_SymbolicLinkProvider.c index c93c087..ea88a8b 100644 --- a/src/logicalfile/LMI_SymbolicLinkProvider.c +++ b/src/logicalfile/LMI_SymbolicLinkProvider.c @@ -25,6 +25,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_SymbolicLinkInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_SymbolicLinkCleanup( @@ -61,18 +62,18 @@ static CMPIStatus LMI_SymbolicLinkGetInstance( const CMPIObjectPath* cop, const char** properties) { - LMI_SymbolicLink lmi_file; - const char *path; - char rpath[PATH_MAX]; + CMPIStatus st = {.rc = CMPI_RC_OK}; + logicalfile_t logicalfile; - LMI_SymbolicLink_InitFromObjectPath(&lmi_file, _cb, cop); - path = KChars(lmi_file.Name.value); - fill_basic(SymbolicLink, path, S_IFLNK, "No such symlink: %s"); - realpath(path, rpath); - LMI_SymbolicLink_Set_TargetFile(&lmi_file, rpath); + st = lmi_check_required(_cb, cop); + check_status(st); - KReturnInstance(cr, lmi_file); - CMReturn(CMPI_RC_OK); + LMI_SymbolicLink_InitFromObjectPath(&logicalfile.lf.symboliclink, _cb, cop); + st = stat_logicalfile_and_fill(_cb, &logicalfile, S_IFLNK, "No such symlink: %s"); + check_status(st); + + KReturnInstance(cr, logicalfile.lf.symboliclink); + return st; } static CMPIStatus LMI_SymbolicLinkCreateInstance( @@ -155,3 +156,6 @@ KONKRET_REGISTRATION( "LMI_SymbolicLink", "instance method") /* vi: set et: */ +/* Local Variables: */ +/* indent-tabs-mode: nil */ +/* End: */ diff --git a/src/logicalfile/LMI_UnixDeviceFileProvider.c b/src/logicalfile/LMI_UnixDeviceFileProvider.c index 4d09efa..2d48d35 100644 --- a/src/logicalfile/LMI_UnixDeviceFileProvider.c +++ b/src/logicalfile/LMI_UnixDeviceFileProvider.c @@ -25,6 +25,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_UnixDeviceFileInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_UnixDeviceFileCleanup( @@ -61,23 +62,18 @@ static CMPIStatus LMI_UnixDeviceFileGetInstance( const CMPIObjectPath* cop, const char** properties) { - LMI_UnixDeviceFile lmi_file; - const char *path; - char tmp[16]; - - LMI_UnixDeviceFile_InitFromObjectPath(&lmi_file, _cb, cop); - path = KChars(lmi_file.Name.value); - fill_basic(UnixDeviceFile, path, S_IFCHR | S_IFBLK, "No such device: %s"); - - sprintf(tmp, "%lu", sb.st_rdev); - LMI_UnixDeviceFile_Set_DeviceId(&lmi_file, tmp); - sprintf(tmp, "%u", major(sb.st_rdev)); - LMI_UnixDeviceFile_Set_DeviceMajor(&lmi_file, tmp); - sprintf(tmp, "%u", minor(sb.st_rdev)); - LMI_UnixDeviceFile_Set_DeviceMinor(&lmi_file, tmp); - - KReturnInstance(cr, lmi_file); - CMReturn(CMPI_RC_OK); + CMPIStatus st = {.rc = CMPI_RC_OK}; + logicalfile_t logicalfile; + + st = lmi_check_required(_cb, cop); + check_status(st); + + LMI_UnixDeviceFile_InitFromObjectPath(&logicalfile.lf.unixdevicefile, _cb, cop); + st = stat_logicalfile_and_fill(_cb, &logicalfile, S_IFCHR | S_IFBLK, "No such device: %s"); + check_status(st); + + KReturnInstance(cr, logicalfile.lf.unixdevicefile); + return st; } static CMPIStatus LMI_UnixDeviceFileCreateInstance( @@ -160,3 +156,6 @@ KONKRET_REGISTRATION( "LMI_UnixDeviceFile", "instance method") /* vi: set et: */ +/* Local Variables: */ +/* indent-tabs-mode: nil */ +/* End: */ diff --git a/src/logicalfile/LMI_UnixDirectoryProvider.c b/src/logicalfile/LMI_UnixDirectoryProvider.c index bdd1245..04de5cc 100644 --- a/src/logicalfile/LMI_UnixDirectoryProvider.c +++ b/src/logicalfile/LMI_UnixDirectoryProvider.c @@ -27,6 +27,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_UnixDirectoryInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_UnixDirectoryCleanup( @@ -63,8 +64,18 @@ static CMPIStatus LMI_UnixDirectoryGetInstance( const CMPIObjectPath* cop, const char** properties) { - get_instance(UnixDirectory, S_IFDIR, "No such directory: %s"); - CMReturn(CMPI_RC_OK); + CMPIStatus st = {.rc = CMPI_RC_OK}; + logicalfile_t logicalfile; + + st = lmi_check_required(_cb, cop); + check_status(st); + + LMI_UnixDirectory_InitFromObjectPath(&logicalfile.lf.unixdirectory, _cb, cop); + st = stat_logicalfile_and_fill(_cb, &logicalfile, S_IFDIR, "Not a directory: %s"); + check_status(st); + + KReturnInstance(cr, logicalfile.lf.unixdirectory); + return st; } static CMPIStatus LMI_UnixDirectoryCreateInstance( @@ -167,3 +178,6 @@ KONKRET_REGISTRATION( "LMI_UnixDirectory", "instance method") /* vi: set et: */ +/* Local Variables: */ +/* indent-tabs-mode: nil */ +/* End: */ diff --git a/src/logicalfile/LMI_UnixFileProvider.c b/src/logicalfile/LMI_UnixFileProvider.c index 5da5bb0..b9be867 100644 --- a/src/logicalfile/LMI_UnixFileProvider.c +++ b/src/logicalfile/LMI_UnixFileProvider.c @@ -32,6 +32,8 @@ static const CMPIBroker* _cb = NULL; static pthread_mutex_t selinux_mutex; static struct selabel_handle *_selabel_hnd = NULL; +/* XXX: selabel_close() and freecon() do no work as expected + * see bug #1008924 */ static struct selabel_handle *get_selabel_handle() { static struct timeval timestamp = {.tv_sec = 0, .tv_usec = 0}; @@ -66,7 +68,7 @@ static struct selabel_handle *get_selabel_handle() static void LMI_UnixFileInitialize() { - lmi_init_logging(LMI_UnixFile_ClassName, _cb); + lmi_init(provider_name, _cb, provider_config_defaults); #ifdef LOGICALFILE_SELINUX pthread_mutex_init(&selinux_mutex, NULL); #endif @@ -117,8 +119,9 @@ static CMPIStatus LMI_UnixFileGetInstance( struct stat sb; char aux[BUFLEN]; const char *path; + char *fsname; - st = lmi_check_required(_cb, cop, UNIXFILE); + st = lmi_check_required(_cb, cop); if (st.rc != CMPI_RC_OK) { return st; } @@ -130,6 +133,16 @@ static CMPIStatus LMI_UnixFileGetInstance( snprintf(aux, BUFLEN, "Can't stat file: %s", path); CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, aux); } + /* set ignored stuff */ + LMI_UnixFile_Set_FSCreationClassName(&lmi_file, FSCREATIONCLASSNAME); + st = get_fsname_from_stat(_cb, &sb, &fsname); + check_status(st); + LMI_UnixFile_Set_FSName(&lmi_file, fsname); + free(fsname); + get_class_from_stat(&sb, aux); + LMI_UnixFile_Set_LFCreationClassName(&lmi_file, aux); + + /* set unix-specific stuff */ LMI_UnixFile_Set_Name(&lmi_file, path); sprintf(aux, "%u", sb.st_uid); LMI_UnixFile_Set_UserID(&lmi_file, aux); @@ -248,3 +261,6 @@ KONKRET_REGISTRATION( "LMI_UnixFile", "instance method") /* vi: set et: */ +/* Local Variables: */ +/* indent-tabs-mode: nil */ +/* End: */ diff --git a/src/logicalfile/LMI_UnixSocketProvider.c b/src/logicalfile/LMI_UnixSocketProvider.c index 56fb6bd..2da6aad 100644 --- a/src/logicalfile/LMI_UnixSocketProvider.c +++ b/src/logicalfile/LMI_UnixSocketProvider.c @@ -25,6 +25,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_UnixSocketInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_UnixSocketCleanup( @@ -61,8 +62,18 @@ static CMPIStatus LMI_UnixSocketGetInstance( const CMPIObjectPath* cop, const char** properties) { - get_instance(UnixSocket, S_IFSOCK, "No such socket: %s"); - CMReturn(CMPI_RC_OK); + CMPIStatus st = {.rc = CMPI_RC_OK}; + logicalfile_t logicalfile; + + st = lmi_check_required(_cb, cop); + check_status(st); + + LMI_UnixSocket_InitFromObjectPath(&logicalfile.lf.unixsocket, _cb, cop); + st = stat_logicalfile_and_fill(_cb, &logicalfile, S_IFSOCK, "No such socket: %s"); + check_status(st); + + KReturnInstance(cr, logicalfile.lf.unixsocket); + return st; } static CMPIStatus LMI_UnixSocketCreateInstance( @@ -145,3 +156,6 @@ KONKRET_REGISTRATION( "LMI_UnixSocket", "instance method") /* vi: set et: */ +/* Local Variables: */ +/* indent-tabs-mode: nil */ +/* End: */ diff --git a/src/logicalfile/doc/Makefile b/src/logicalfile/doc/Makefile new file mode 100644 index 0000000..f368704 --- /dev/null +++ b/src/logicalfile/doc/Makefile @@ -0,0 +1,159 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source +# the i18n builder cannot share the environment and doctrees with the others +I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext mof + +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " singlehtml to make a single large HTML file" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " devhelp to make HTML files and a Devhelp project" + @echo " epub to make an epub" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " latexpdf to make LaTeX files and run them through pdflatex" + @echo " text to make text files" + @echo " man to make manual pages" + @echo " texinfo to make Texinfo files" + @echo " info to make Texinfo files and run them through makeinfo" + @echo " gettext to make PO message catalogs" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +mof: + make -C source/mof + +mof-clean: + make -C source/mof clean + +clean: mof-clean + -rm -rf $(BUILDDIR)/* + +html: mof + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +singlehtml: + $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml + @echo + @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/OpenLMILogicalFile.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/OpenLMILogicalFile.qhc" + +devhelp: + $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp + @echo + @echo "Build finished." + @echo "To view the help file:" + @echo "# mkdir -p $$HOME/.local/share/devhelp/OpenLMILogicalFile" + @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/OpenLMILogicalFile" + @echo "# devhelp" + +epub: + $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub + @echo + @echo "Build finished. The epub file is in $(BUILDDIR)/epub." + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make' in that directory to run these through (pdf)latex" \ + "(use \`make latexpdf' here to do that automatically)." + +latexpdf: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo "Running LaTeX files through pdflatex..." + $(MAKE) -C $(BUILDDIR)/latex all-pdf + @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." + +text: + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text + @echo + @echo "Build finished. The text files are in $(BUILDDIR)/text." + +man: + $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man + @echo + @echo "Build finished. The manual pages are in $(BUILDDIR)/man." + +texinfo: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo + @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." + @echo "Run \`make' in that directory to run these through makeinfo" \ + "(use \`make info' here to do that automatically)." + +info: + $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo + @echo "Running Texinfo files through makeinfo..." + make -C $(BUILDDIR)/texinfo info + @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." + +gettext: + $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale + @echo + @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/src/logicalfile/doc/source/conf.py b/src/logicalfile/doc/source/conf.py new file mode 100644 index 0000000..973efbb --- /dev/null +++ b/src/logicalfile/doc/source/conf.py @@ -0,0 +1,241 @@ +# -*- coding: utf-8 -*- +# +# OpenLMI LogicalFile documentation +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.viewcode'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'OpenLMI LogicalFile' +copyright = u'2012-2013, Red Hat Inc.' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.2' +# The full version, including alpha/beta/rc tags. +release = '0.2' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# "<project> v<release> documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a <link> tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'OpenLMILogicalFiledoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'OpenLMILogicalFile.tex', u'OpenLMI LogicalFile Documentation', + u'Jan Synáček', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'openlmilogicalfile', u'OpenLMI LogicalFile Documentation', + [u'Jan Synáček'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'OpenLMILogicalFile', u'OpenLMI LogicalFile Documentation', + u'Jan Synáček', 'OpenLMILogicalFile', 'OpenLMI LogicalFile provider.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' diff --git a/src/logicalfile/doc/source/index.rst b/src/logicalfile/doc/source/index.rst new file mode 100644 index 0000000..c2fd199 --- /dev/null +++ b/src/logicalfile/doc/source/index.rst @@ -0,0 +1,25 @@ +OpenLMI LogicalFile Provider documentation +========================================== +OpenLMI LogicalFile is a CIM provider which provides a way to read information +about files and directories. The provider also allows to traverse the file +hierarchy, create and remove empty directories. + +The provider implements a part of the +`CIM System schema <http://dmtf.org/standards/cim/schemas>`_ (sections "Local +File Systems" and "Unix System"). + + +Contents: + +.. toctree:: + :maxdepth: 2 + + usage + +OpenLMI LogicalFile CIM Classes: + +.. toctree:: + :maxdepth: 1 + + mof/tree + mof/index diff --git a/src/logicalfile/doc/source/mof/Makefile b/src/logicalfile/doc/source/mof/Makefile new file mode 100644 index 0000000..52a037d --- /dev/null +++ b/src/logicalfile/doc/source/mof/Makefile @@ -0,0 +1,14 @@ +all: index.rst + +TOPDIR=../../../../.. +MOFS=$(TOPDIR)/mof/60_LMI_LogicalFile.mof + +clean: + rm -f *.rst + +index.rst: $(MOFS) + python $(TOPDIR)/tools/openlmi-doc-class2rst -H header.txt -M `echo $(MOFS) | sed 's/ / -M /g'` \ + -S /usr/share/mof/cim-current/CIM_Schema.mof \ + -S $(TOPDIR)/mof/05_LMI_Qualifiers.mof \ + -S $(TOPDIR)/mof/30_LMI_Jobs.mof \ + `cat $(MOFS) | grep "^class" | cut -d ' ' -f 2 | sed 's/://'` diff --git a/src/logicalfile/doc/source/mof/header.txt b/src/logicalfile/doc/source/mof/header.txt new file mode 100644 index 0000000..cc06402 --- /dev/null +++ b/src/logicalfile/doc/source/mof/header.txt @@ -0,0 +1,2 @@ +Class reference +=============== diff --git a/src/logicalfile/doc/source/usage.rst b/src/logicalfile/doc/source/usage.rst new file mode 100644 index 0000000..ecd55d0 --- /dev/null +++ b/src/logicalfile/doc/source/usage.rst @@ -0,0 +1,169 @@ +OpenLMI LogicalFile usage +========================= + +There are two basic types of classes in the LogicalFile provider. + +:ref:`CIM_LogicalFile <CIM-LogicalFile>` subclasses: + +* :ref:`LMI_FIFOPipeFile <LMI-FIFOPipeFile>` +* :ref:`LMI_UnixDeviceFile <LMI-UnixDeviceFile>` +* :ref:`LMI_UnixDirectory <LMI-UnixDirectory>` +* :ref:`LMI_UnixSocket <LMI-UnixSocket>` +* :ref:`LMI_DataFile <LMI-DataFile>` +* :ref:`LMI_SymbolicLink <LMI-SymbolicLink>` + +Subclasses derived from :ref:`CIM_LogicalFile <CIM-LogicalFile>` represent basic types of files and their +system independent properties, such as if the file is readable or its +modification time. The classes' names are self-explanatory. :ref:`LMI_SymbolicLink +<LMI-SymbolicLink>` represents symbolic link files, :ref:`LMI_UnixDeviceFile +<LMI-UnixDeviceFile>` represents unix device files, etc. + +The other type of class is :ref:`LMI_UnixFile <LMI-UnixFile>`. It is used in the +Unix-like environment. Its properties are tied to the system -- Linux in our +case. For example, the group id of the owner or the inode number are among those +properties. + +To provide ways to connect the file subclasses together, LogicalFile also +defines a few associations. + +Association classes: + +* :ref:`LMI_RootDirectory <LMI-RootDirectory>` +* :ref:`LMI_FileIdentity <LMI-FileIdentity>` +* :ref:`LMI_DirectoryContainsFile <LMI-DirectoryContainsFile>` + +:ref:`LMI_RootDirectory <LMI-RootDirectory>` is used to connect the computer +system to its root directory. + +:ref:`LMI_FileIdentity <LMI-FileIdentity>` associates the system-independent +:ref:`CIM_LogicalFile <CIM-LogicalFile>` subclasses to their respective +:ref:`LMI_UnixFile <LMI-UnixFile>` equivalents that are dependent on the +system. + +:ref:`LMI_DirectoryContainsFile <LMI-DirectoryContainsFile>` serves as a tool to +show contents of a directory. Note that directory is usually just a type of +file. + +Deviations from the schema +-------------------------- + +No classes that represent files have the ``EnumerateInstances`` method +implemented. The reason for this is that it would be very resource intensive to +list all the files on the given filesystem. Even more so, for example, all the +symlinks on the filesystem. For that reason, every LogicalFile class +implements only its ``GetInstance`` method. + +The objectpath of the logical file classes consists of these properties: + +* :ref:`CSCreationClassName <CIM-LogicalFile-CSCreationClassName>` +* :ref:`CSName <CIM-LogicalFile-CSName>` +* :ref:`FSCreationClassName <CIM-LogicalFile-FSCreationClassName>` +* :ref:`FSName <CIM-LogicalFile-FSName>` +* :ref:`CreationClassName <CIM-LogicalFile-CreationClassName>` + (:ref:`LFCreationClassName <CIM-UnixFile-LFCreationClassName>` for + :ref:`LMI_UnixFile <LMI-UnixFile>`) +* :ref:`Name <CIM-LogicalFile-Name>` (:ref:`LFName <CIM-UnixFile-LFName>` for + :ref:`LMI_UnixFile <LMI-UnixFile>`) + +When getting an instance, it's usually required that all of the key properties +are specified. However, it is impossible, or at least needlessly complicated, to +know some of them when querying remote machines. For example, if I want to see +information about the file '/home/user/myfile' on a remote computer, I don't +want to specify the filesystem it resides on or the type of the file. + +Therefore, the only mandatory key properties are :ref:`CSCreationClassName +<CIM-LogicalFile-CSCreationClassName>`, :ref:`CSName <CIM-LogicalFile-CSName>` +and :ref:`Name <CIM-LogicalFile-Name>` (of :ref:`LFName <CIM-UnixFile-LFName>` +in case of :ref:`LMI_UnixFile <LMI-UnixFile>`). :ref:`FSName +<CIM-UnixFile-FSName>`, :ref:`FSCreationClassName +<CIM-LogicalFile-FSCreationClassName>` and :ref:`CreationClassName +<CIM-LogicalFile-CreationClassName>` are ignored. They are correctly filled in +after the instance has been properly returned. + +To have an entry point into the Unix filesystems, an association has been +added. It binds the computer system and its root directory. See +:ref:`LMI_RootDirectory <LMI-RootDirectory>`. + +:ref:`LMI_UnixFile <LMI-UnixFile>` has been extended to hold additional +properties. Currently, those are :ref:`SELinuxCurrentContext +<LMI-UnixFile-SELinuxCurrentContext>` and :ref:`SELinuxExpectedContext +<LMI-UnixFile-SELinuxExpectedContext>`. Should there be need for more +additions, this class can be easily extended. + +Getting files +------------- +All further code assumes that a connection object has been created and the +default namespace (root/cimv2) is used. Also, the system's instance must have +been acquired. + +:: + + # plain http connections will likely be refused + c = connect('https://myhost') + # namespace alias for convenience + ns = c.root.cimv2 + system = ns.Linux_ComputerSystem.first_instance() + +Get an instance of the home directory:: + + name_dict = {'CSCreationClassName':system.classname, + 'CSName':system.name, + 'CreationClassName':'ignored', + 'FSCreationClassName':'ignored', + 'FSName':'ignored', + 'Name':'/home/jsynacek'} + name = ns.LMI_UnixDirectory.new_instance_name(name_dict) + home = name.to_instance() + print home.Name + +Get an instance of a temporary file and see its selinux contexts using the +:ref:`LMI_FileIdentity <LMI-FileIdentity>`:: + + name_dict = {'CSCreationClassName':system.classname, + 'CSName':system.name, + 'LFCreationClassName':'ignored', + 'FSCreationClassName':'ignored', + 'FSName':'ignored', + 'LFName':'/var/tmp/data_file'} + name = ns.LMI_UnixFile.new_instance_name(name_dict) + unixdata = name.to_instance() + data = unixdata.first_associator(AssocClass='LMI_FileIdentity') + print unixdata.SELinuxCurrentContext + print unixdata.SELinuxExpectedContext + print data.Readable + print data.Writeable + print data.Executable + +Get an instance of a symlink and check where it points to:: + + name_dict = {'CSCreationClassName':system.classname, + 'CSName':system.name, + 'LFCreationClassName':'ignored', + 'FSCreationClassName':'ignored', + 'FSName':'ignored', + 'LFName':'/home/jsynacek/test-link'} + name = ns.LMI_UnixFile.new_instance_name(name_dict) + unixsymlink = name.to_instance() + symlink = unixsymlink.first_associator(AssocClass='LMI_FileIdentity') + print symlink.TargetFile + +Association classes examples +---------------------------- + +List a directory:: + + files = home.associators(AssocClass='LMI_DirectoryContainsFile') + for f in sorted(files, key=lambda x: x.Name): + print f.Name + + +Get the root directory:: + + root = system.first_associator(AssocClass='LMI_RootDirectory') + print root.Name + +.. note:: + + For a more complex example of how to use the LogicalFile provider, please + refer to the `OpenLMI LogicalFile script + <https://github.com/openlmi/openlmi-scripts/tree/master/commands/logicalfile/lmi/scripts/logicalfile>`_. diff --git a/src/logicalfile/file.c b/src/logicalfile/file.c index e6968de..3e9c834 100644 --- a/src/logicalfile/file.c +++ b/src/logicalfile/file.c @@ -19,113 +19,34 @@ */ #include "file.h" +const ConfigEntry *provider_config_defaults = NULL; +const char *provider_name = "logicalfile"; + + CMPIStatus lmi_check_required( const CMPIBroker *b, - const CMPIObjectPath *o, - const enum RequiredNames rn) + const CMPIObjectPath *o) { const char *prop; - const char *errmsg = NULL; - char *path = NULL; /* check computer system creation class name */ if (CMIsNullValue(CMGetKey(o, "CSCreationClassName", NULL))) { - errmsg = "CSCreationClassName is empty"; - goto done; + CMReturnWithChars(b, CMPI_RC_ERR_FAILED, "CSCreationClassName is empty"); } prop = get_string_property_from_op(o, "CSCreationClassName"); if (strcmp(prop, lmi_get_system_creation_class_name()) != 0) { - errmsg = "Wrong CSCreationClassName"; - goto done; + CMReturnWithChars(b, CMPI_RC_ERR_FAILED, "Wrong CSCreationClassName"); } /* check fqdn */ if (CMIsNullValue(CMGetKey(o, "CSName", NULL))) { - errmsg = "CSName is empty"; - goto done; + CMReturnWithChars(b, CMPI_RC_ERR_FAILED, "CSName is empty"); } prop = get_string_property_from_op(o, "CSName"); if (strcmp(prop, lmi_get_system_name()) != 0) { - errmsg = "Wrong CSName"; - goto done; + CMReturnWithChars(b, CMPI_RC_ERR_FAILED, "Wrong CSName"); } - if (rn == UNIXFILE) { - /* check creation class name */ - char fileclass[BUFLEN]; - if (CMIsNullValue(CMGetKey(o, "LFCreationClassName", NULL))) { - errmsg = "LFCreationClassName is empty"; - goto done; - } - prop = get_string_property_from_op(o, "LFCreationClassName"); - if (get_class_from_path(get_string_property_from_op(o, "LFName"), fileclass) != 0) { - errmsg = "Can't get class from path"; - goto done; - } - if (strcmp(prop, fileclass) != 0) { - errmsg = "LFCreationClassName doesn't match the file's type"; - goto done; - } - if (CMIsNullValue(CMGetKey(o, "LFName", NULL))) { - errmsg = "LFName is empty"; - goto done; - } - if (get_fsname_from_path(get_string_property_from_op(o, "LFName"), &path) < 0) { - errmsg = "Can't get FSName from path"; - goto done; - } - } else if (rn == LOGICALFILE) { - /* check creation class name */ - if (CMIsNullValue(CMGetKey(o, "CreationClassName", NULL))) { - errmsg = "CreationClassName is empty"; - goto done; - } - prop = get_string_property_from_op(o, "CreationClassName"); - if (!CMClassPathIsA(b, o, prop, NULL)) { - errmsg = "CreationClassName and the class name don't match"; - goto done; - } - if (CMIsNullValue(CMGetKey(o, "Name", NULL))) { - errmsg = "Name is empty"; - goto done; - } - if (get_fsname_from_path(get_string_property_from_op(o, "Name"), &path) < 0) { - errmsg = "Can't get FSName from path"; - goto done; - } - } else { - /* not possible! */ - assert(0); - } - - /* check fs creation class name and fsname */ - if (CMIsNullValue(CMGetKey(o, "FSCreationClassName", NULL))) { - errmsg = "FSCreationClassName is empty"; - goto done; - } - prop = get_string_property_from_op(o, "FSCreationClassName"); - if (strcmp(prop, FSCREATIONCLASSNAME) != 0) { - errmsg = "Wrong FSCreationClassName"; - goto done; - } - - if (CMIsNullValue(CMGetKey(o, "FSName", NULL))) { - errmsg = "FSName is empty"; - goto done; - } - prop = get_string_property_from_op(o, "FSName"); - if (strcmp(prop, path) != 0) { - errmsg = "Wrong FSName"; - goto done; - } - -done: - if (path) { - free(path); - } - if (errmsg) { - CMReturnWithChars(b, CMPI_RC_ERR_FAILED, errmsg); - } CMReturn(CMPI_RC_OK); } @@ -155,19 +76,16 @@ int get_class_from_path(const char *path, char *fileclass) return rc; } -int get_fsname_from_stat(const struct stat *sb, char **fname) +CMPIStatus get_fsname_from_stat(const CMPIBroker *b, const struct stat *sb, char **fname) { - static struct udev *udev_ctx = NULL; + struct udev *udev_ctx; struct udev_device *udev_dev; const char *dev_name; - int rc = 0; + CMPIStatus st = {.rc = CMPI_RC_OK}; + udev_ctx = udev_new(); if (!udev_ctx) { - udev_ctx = udev_new(); - if (!udev_ctx) { - rc = -1; - goto err; - } + return_with_status(b, &st, ERR_FAILED, "Could not create udev context"); } char dev_id[16]; @@ -175,26 +93,34 @@ int get_fsname_from_stat(const struct stat *sb, char **fname) udev_dev = udev_device_new_from_device_id(udev_ctx, dev_id); if ((dev_name = udev_device_get_property_value(udev_dev, "ID_FS_UUID_ENC"))) { - rc = asprintf(fname, "UUID=%s", dev_name); + if (asprintf(fname, "UUID=%s", dev_name) < 0) { + return_with_status(b, &st, ERR_FAILED, "asprintf failed"); + } } else if ((dev_name = udev_device_get_property_value(udev_dev, "DEVNAME"))) { - rc = asprintf(fname, "DEVICE=%s", dev_name); + if (asprintf(fname, "DEVICE=%s", dev_name) < 0) { + return_with_status(b, &st, ERR_FAILED, "asprintf failed"); + } } else { - rc = asprintf(fname, "Unknown"); + if (asprintf(fname, "Unknown") < 0) { + return_with_status(b, &st, ERR_FAILED, "asprintf failed"); + } } -err: - return rc; + udev_device_unref(udev_dev); + udev_unref(udev_ctx); + + return st; } -int get_fsname_from_path(const char *path, char **fsname) +CMPIStatus get_fsname_from_path(const CMPIBroker *b, const char *path, char **fsname) { + CMPIStatus st = {.rc = CMPI_RC_OK}; struct stat sb; - int rc; - rc = lstat(path, &sb); - if (rc == 0) { - rc = get_fsname_from_stat(&sb, fsname); + if (lstat(path, &sb) < 0) { + return_with_status(b, &st, ERR_FAILED, "lstat(2) failed"); } - return rc; + + return get_fsname_from_stat(b, &sb, fsname); } const char *get_string_property_from_op(const CMPIObjectPath *o, const char *prop) @@ -204,6 +130,92 @@ const char *get_string_property_from_op(const CMPIObjectPath *o, const char *pro return KChars(d.value.string); } +CMPIStatus check_assoc_class( + const CMPIBroker *cb, + const char *namespace, + const char *assocClass, + const char *class) +{ + CMPIObjectPath *o; + CMPIStatus st = {.rc = CMPI_RC_OK}; + + o = CMNewObjectPath(cb, namespace, class, &st); + if (!o || st.rc) { + CMRelease(o); + return st; + } + if (assocClass && !CMClassPathIsA(cb, o, assocClass, &st)) { + CMRelease(o); + st.rc = RC_ERR_CLASS_CHECK_FAILED; + return st; + } + CMRelease(o); + return st; +} + +CMPIStatus stat_logicalfile_and_fill( + const CMPIBroker *b, + logicalfile_t *lf, + mode_t mode, + const char *errmsg) +{ + struct stat sb; + char buf[BUFLEN]; + char *fsname = NULL; + const char *path = KChars(lf->lf.datafile.Name.value); + CMPIStatus st = {.rc = CMPI_RC_OK}; + + if (lstat(path, &sb) < 0 || !(sb.st_mode & S_IFMT & mode)) { + snprintf(buf, BUFLEN, errmsg, path); + CMReturnWithChars(b, CMPI_RC_ERR_NOT_FOUND, buf); + } + + get_class_from_stat(&sb, buf); + + st = get_fsname_from_stat(b, &sb, &fsname); + check_status(st); + + switch(mode) { + case S_IFREG: + fill_basic(b, DataFile, &lf->lf.datafile, buf, fsname, sb); + break; + case S_IFCHR: + /* FALLTHROUGH */ + case S_IFBLK: + fill_basic(b, UnixDeviceFile, &lf->lf.unixdevicefile, buf, fsname, sb); + /* device-specific stuff */ + char tmp[16]; + sprintf(tmp, "%lu", sb.st_rdev); + LMI_UnixDeviceFile_Set_DeviceId(&lf->lf.unixdevicefile, tmp); + sprintf(tmp, "%u", major(sb.st_rdev)); + LMI_UnixDeviceFile_Set_DeviceMajor(&lf->lf.unixdevicefile, tmp); + sprintf(tmp, "%u", minor(sb.st_rdev)); + LMI_UnixDeviceFile_Set_DeviceMinor(&lf->lf.unixdevicefile, tmp); + break; + case S_IFDIR: + fill_basic(b, UnixDirectory, &lf->lf.unixdirectory, buf, fsname, sb); + break; + case S_IFIFO: + fill_basic(b, FIFOPipeFile, &lf->lf.fifopipefile, buf, fsname, sb); + break; + case S_IFLNK: + fill_basic(b, SymbolicLink, &lf->lf.symboliclink, buf, fsname, sb); + /* symlink-specific stuff */ + char rpath[PATH_MAX]; + const char *path; + path = KChars(lf->lf.symboliclink.Name.value); + realpath(path, rpath); + LMI_SymbolicLink_Set_TargetFile(&lf->lf.symboliclink, rpath); + break; + default: + /* impossible */ + assert(0); + } + + free(fsname); + return st; +} + void _dump_objectpath(const CMPIObjectPath *o) { printf("OP: %s\n", CMGetCharsPtr(o->ft->toString(o, NULL), NULL)); diff --git a/src/logicalfile/file.h b/src/logicalfile/file.h index b7ecb53..953ff18 100644 --- a/src/logicalfile/file.h +++ b/src/logicalfile/file.h @@ -30,6 +30,12 @@ #include <konkret/konkret.h> #include <assert.h> #include <libudev.h> +#include "LMI_DataFile.h" +#include "LMI_UnixDeviceFile.h" +#include "LMI_SymbolicLink.h" +#include "LMI_UnixDirectory.h" +#include "LMI_UnixSocket.h" +#include "LMI_FIFOPipeFile.h" #include "globals.h" #ifndef BUFLEN @@ -39,12 +45,18 @@ #define PATH_MAX 4096 #endif +const ConfigEntry *provider_config_defaults; +const char *provider_name; + #define FSCREATIONCLASSNAME "LMI_LocalFileSystem" #define GROUP_COMPONENT "GroupComponent" #define PART_COMPONENT "PartComponent" #define SAME_ELEMENT "SameElement" #define SYSTEM_ELEMENT "SystemElement" +/* CMPI_RC_ERR_<error> values end at 200. 0xFF should be safe. */ +#define RC_ERR_CLASS_CHECK_FAILED 0xFF + #define sb_permmask(sb) ((sb).st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)) #define sb_isreadable(sb) ( \ (sb_permmask(sb) & S_IRUSR) || \ @@ -71,67 +83,56 @@ type##_Set_FSName((obj), (fsname)); \ type##_Set_CreationClassName((obj), (creation_class)); -#define fill_basic(cmpitype, path, stattype, error) \ - struct stat sb; \ - char errmsg[BUFLEN]; \ - \ - if (lstat((path), &sb) < 0 || !(sb.st_mode & S_IFMT & (stattype))) { \ - snprintf(errmsg, BUFLEN, error, (path)); \ - CMReturnWithChars(_cb, CMPI_RC_ERR_NOT_FOUND, errmsg); \ - } \ - \ - LMI_##cmpitype##_Set_Readable(&lmi_file, sb_isreadable(sb)); \ - LMI_##cmpitype##_Set_Writeable(&lmi_file, sb_iswriteable(sb)); \ - LMI_##cmpitype##_Set_Executable(&lmi_file, sb_isexecutable(sb)); \ - LMI_##cmpitype##_Set_FileSize(&lmi_file, sb.st_size); \ - LMI_##cmpitype##_Set_LastAccessed(&lmi_file, CMNewDateTimeFromBinary(_cb, stoms(sb.st_atime), 0, NULL)); \ - LMI_##cmpitype##_Set_LastModified(&lmi_file, CMNewDateTimeFromBinary(_cb, stoms(sb.st_mtime), 0, NULL)); +#define fill_basic(b, cmpitype, lmi_file, creation_class_name, fsname, sb) \ + LMI_##cmpitype##_Set_CreationClassName(lmi_file, creation_class_name); \ + LMI_##cmpitype##_Set_FSCreationClassName(lmi_file, FSCREATIONCLASSNAME); \ + LMI_##cmpitype##_Set_FSName(lmi_file, fsname); \ + LMI_##cmpitype##_Set_Readable(lmi_file, sb_isreadable(sb)); \ + LMI_##cmpitype##_Set_Writeable(lmi_file, sb_iswriteable(sb)); \ + LMI_##cmpitype##_Set_Executable(lmi_file, sb_isexecutable(sb)); \ + LMI_##cmpitype##_Set_FileSize(lmi_file, sb.st_size); \ + LMI_##cmpitype##_Set_LastAccessed(lmi_file, CMNewDateTimeFromBinary(b, stoms(sb.st_atime), 0, NULL)); \ + LMI_##cmpitype##_Set_LastModified(lmi_file, CMNewDateTimeFromBinary(b, stoms(sb.st_mtime), 0, NULL)); -#define get_instance(cmpitype, stattype, error) \ - LMI_##cmpitype lmi_file; \ - CMPIStatus st; \ - \ - LMI_##cmpitype##_InitFromObjectPath(&lmi_file, _cb, cop); \ - st = lmi_check_required(_cb, cop, LOGICALFILE); \ +#define check_status(st) \ if (st.rc != CMPI_RC_OK) { \ return st; \ - } \ - fill_basic(cmpitype, KChars(lmi_file.Name.value), stattype, error) \ - KReturnInstance(cr, lmi_file); + } -#define check_assoc_class(b, ns, assoc_class, cls) \ -{ \ - CMPIObjectPath *o; \ - CMPIStatus st; \ - \ - o = CMNewObjectPath(b, ns, cls, &st); \ - if (!o || st.rc) { \ - CMRelease(o); \ - return st; \ - } \ - if (assoc_class && !CMClassPathIsA(b, o, assoc_class, &st)) { \ - CMRelease(o); \ +#define check_class_check_status(st) \ + if (st.rc == RC_ERR_CLASS_CHECK_FAILED) { \ CMReturn(CMPI_RC_OK); \ } \ - CMRelease(o); \ -} + check_status(st); -enum RequiredNames { - LOGICALFILE, - UNIXFILE, -}; +#define return_with_status(b, st, code, msg) \ + KSetStatus2(b, st, code, msg); \ + return *(st); -CMPIStatus lmi_check_required(const CMPIBroker *, const CMPIObjectPath *, const enum RequiredNames); +typedef struct { + union { + LMI_DataFile datafile; + LMI_UnixDeviceFile unixdevicefile; + LMI_UnixDirectory unixdirectory; + LMI_FIFOPipeFile fifopipefile; + LMI_UnixSocket unixsocket; + LMI_SymbolicLink symboliclink; + } lf; +} logicalfile_t; + +CMPIStatus lmi_check_required(const CMPIBroker *, const CMPIObjectPath *); void get_class_from_stat(const struct stat *, char *); int get_class_from_path(const char *, char *); -int get_fsname_from_stat(const struct stat *, char **); -int get_fsname_from_path(const char *, char **); +CMPIStatus get_fsname_from_stat(const CMPIBroker *, const struct stat *, char **); +CMPIStatus get_fsname_from_path(const CMPIBroker *, const char *, char **); const char *get_string_property_from_op(const CMPIObjectPath *, const char *); - +CMPIStatus check_assoc_class(const CMPIBroker *, const char *, const char *, const char *); +CMPIStatus stat_logicalfile_and_fill(const CMPIBroker *, logicalfile_t *, mode_t, const char *); void _dump_objectpath(const CMPIObjectPath *); #endif /* _FILE_H */ /* vi: set et: */ /* Local Variables: */ /* indent-tabs-mode: nil */ +/* c-backslash-max-column: 78 */ /* End: */ diff --git a/src/logicalfile/test/test_basic.py b/src/logicalfile/test/test_basic.py index fbcf6d5..4c210f9 100644 --- a/src/logicalfile/test/test_basic.py +++ b/src/logicalfile/test/test_basic.py @@ -428,73 +428,17 @@ class TestLogicalFile(LogicalFileTestBase): prefix = '' clsname = 'LMI_DataFile' cop = pywbem.CIMInstanceName(classname=clsname, - namespace='root/cimv2', - keybindings={}) - - prop = 'CSCreationClassName' - self.assertRaisesRegexp(pywbem.CIMError, - '%s is empty' % prop, - self.wbemconnection.GetInstance, - cop) - cop.keybindings[prop] = 'BadClass' - self.assertRaisesRegexp(pywbem.CIMError, - 'Wrong %s' % prop, - self.wbemconnection.GetInstance, - cop) - cop.keybindings[prop] = self.SYSTEM_CLASS_NAME - - prop = 'CSName' - self.assertRaisesRegexp(pywbem.CIMError, - '%s is empty' % prop, - self.wbemconnection.GetInstance, - cop) - cop.keybindings[prop] = 'BadClass' - self.assertRaisesRegexp(pywbem.CIMError, - 'Wrong %s' % prop, - self.wbemconnection.GetInstance, - cop) - cop.keybindings[prop] = self.SYSTEM_NAME - - prop = prefix + 'CreationClassName' - self.assertRaisesRegexp(pywbem.CIMError, - '%s is empty' % prop, - self.wbemconnection.GetInstance, - cop) - cop.keybindings[prop] = testfile['class'] - prop = prefix + 'Name' - cop.keybindings[prop] = self.files['dir']['path'] - if is_unixfile: - self.assertRaisesRegexp(pywbem.CIMError, - 'LFCreationClassName doesn\'t match', - self.wbemconnection.GetInstance, - cop) - cop.keybindings[prop] = testfile['path'] - - prop = 'FSCreationClassName' - self.assertRaisesRegexp(pywbem.CIMError, - '%s is empty' % prop, - self.wbemconnection.GetInstance, - cop) - cop.keybindings[prop] = 'BadFS' - self.assertRaisesRegexp(pywbem.CIMError, - 'Wrong %s' % prop, - self.wbemconnection.GetInstance, - cop) - cop.keybindings[prop] = 'LMI_LocalFileSystem' - - prop = 'FSName' - self.assertRaisesRegexp(pywbem.CIMError, - '%s is empty' % prop, - self.wbemconnection.GetInstance, - cop) - cop.keybindings[prop] = 'BadFSName' - self.assertRaisesRegexp(pywbem.CIMError, - 'Wrong %s' % prop, - self.wbemconnection.GetInstance, - cop) - cop.keybindings[prop] = self.fsname - - # finally, test GetInstance on the correct object path + namespace='root/cimv2', + keybindings={ + 'CSCreationClassName':self.SYSTEM_CLASS_NAME, + 'CSName':self.SYSTEM_NAME, + 'FSCreationClassName':'LMI_LocalFileSystem', + 'FSName':self.fsname, + }) + + cop.keybindings[prefix+'CreationClassName'] = testfile['class'] + cop.keybindings[prefix+'Name'] = testfile['path'] + try: self.wbemconnection.GetInstance(cop) except pywbem.CIMError as pe: diff --git a/src/openlmi.c b/src/openlmi.c index 3b46f8d..25cf57c 100644 --- a/src/openlmi.c +++ b/src/openlmi.c @@ -28,11 +28,37 @@ #include <netdb.h> #include <stdio.h> #include <cmpimacs.h> +#include <glib.h> static char *_fqdn = NULL; -static int _log_level = _LMI_DEBUG_DEBUG; static const CMPIBroker *_cb = NULL; -static char *_log_id = NULL; +static char *_provider = NULL; + +// Storage for all keys from configuration files and default configuration option +// Access needs to be mutexed +static GKeyFile *_masterKeyFile = NULL; + +// Mutex for running lmi_init +static pthread_mutex_t _init_mutex = PTHREAD_MUTEX_INITIALIZER; + +// Cache for SystemCreationClassName +static char *_system_creation_class_name = NULL; + +// Cache for log level +static int _log_level = _LMI_DEBUG_NONE; + +// Cache for log stderr +static bool _log_stderr = false; + +static ConfigEntry _toplevel_config_defaults[] = { + { "CIM", "Namespace", "root/cimv2" }, + { "CIM", "SystemClassName", "Linux_ComputerSystem" }, + { "LOG", "Level", "ERROR" }, + { "LOG", "Stderr" , "false" } +}; + +#define TOPLEVEL_CONFIG_FILE "/etc/openlmi/openlmi.conf" +#define PROVIDER_CONFIG_FILE "/etc/openlmi/%s/%s.conf" /** Gets Fully Quantified Domain Name of the system * @return FQDN (must be freed by the caller) @@ -91,16 +117,160 @@ const char *lmi_get_system_name() const char *lmi_get_system_creation_class_name() { - return "Linux_ComputerSystem"; + if (_system_creation_class_name == NULL) { + if (_masterKeyFile == NULL) { + lmi_error("Configuration was not read, using default option"); + return "Linux_ComputerSystem"; + } + _system_creation_class_name = lmi_read_config("CIM", "SystemClassName"); + if (_system_creation_class_name == NULL) { + // This shouldn't happen, SystemClassName should be at least + // in default config keys + return "Linux_ComputerSystem"; + } + } + return _system_creation_class_name; } -void lmi_init_logging(const char *log_id, const CMPIBroker *cb) +char *lmi_read_config(const char *group, const char *key) +{ + if (_masterKeyFile == NULL) { + lmi_warn("Attempted to read config file before calling lmi_init"); + return NULL; + } + return g_key_file_get_string(_masterKeyFile, group, key, NULL); +} + +bool lmi_read_config_boolean(const char *group, const char *key) +{ + char *value = lmi_read_config(group, key); + if (value == NULL) { + return false; + } + char *true_values[] = { "1", "yes", "true", "on" }; + size_t len = sizeof(true_values) / sizeof(true_values[0]); + for (size_t i = 0; i < len; ++i) { + if (strcasecmp(true_values[i], value) == 0) { + free(value); + return true; + } + } + free(value); + return false; +} + +GKeyFile *parse_config(const char *provider_name, const ConfigEntry *provider_config_defaults) { - if (_log_id != NULL) { - free(_log_id); + GError *error = NULL; + char *providerconf; + + // Get all configuration options to masterKeyFile + GKeyFile *masterKeyFile = g_key_file_new(); + + // Read top-level openlmi configuration + if (!g_key_file_load_from_file(masterKeyFile, TOPLEVEL_CONFIG_FILE, G_KEY_FILE_NONE, &error)) { + lmi_debug("Can't read openlmi top-level config file %s: %s", TOPLEVEL_CONFIG_FILE, error->message); + } + + // Read provider-specific configuration + if (asprintf(&providerconf, PROVIDER_CONFIG_FILE, provider_name, provider_name) <= 0) { + lmi_error("Memory allocation failed"); + g_key_file_free(masterKeyFile); + return NULL; + } + GKeyFile *providerKeyFile; + if ((providerKeyFile = g_key_file_new()) == NULL) { + lmi_error("Memory allocation failed"); + g_key_file_free(masterKeyFile); + return NULL; + } + if (!g_key_file_load_from_file(providerKeyFile, providerconf, G_KEY_FILE_NONE, &error)) { + lmi_debug("Can't read provider specific config file %s: %s", providerconf, error->message); + } + + // Merge provider config to _masterKeyFile + gsize groups_len, keys_len, i, j; + gchar *v; + gchar **groups = g_key_file_get_groups(providerKeyFile, &groups_len), **keys; + if (groups != NULL) { + for (i = 0; i < groups_len; ++i) { + keys = g_key_file_get_keys(providerKeyFile, groups[i], &keys_len, &error); + for (j = 0; j < keys_len; ++j) { + v = g_key_file_get_value(providerKeyFile, groups[i], keys[j], &error); + g_key_file_set_value(masterKeyFile, groups[i], keys[j], v); + free(v); + } + g_strfreev(keys); + } + g_strfreev(groups); } - _log_id = strdup(log_id); + g_key_file_free(providerKeyFile); + + // Fill in default values where nothing gets read from config file. + // Provider-specific configs first + gsize len = 0; + if (provider_config_defaults != NULL) { + len = sizeof(provider_config_defaults) / sizeof(ConfigEntry); + } + for (i = 0; i < len; i++) { + if (!g_key_file_has_key(masterKeyFile, + provider_config_defaults[i].group, + provider_config_defaults[i].key, NULL)) { + + g_key_file_set_value(masterKeyFile, + provider_config_defaults[i].group, + provider_config_defaults[i].key, + provider_config_defaults[i].value); + } + } + + // Top-level configs + len = sizeof(_toplevel_config_defaults)/sizeof(ConfigEntry); + for (i = 0; i < len; i++) { + if (!g_key_file_has_key(masterKeyFile, + _toplevel_config_defaults[i].group, + _toplevel_config_defaults[i].key, NULL)) { + + g_key_file_set_value(masterKeyFile, + _toplevel_config_defaults[i].group, + _toplevel_config_defaults[i].key, + _toplevel_config_defaults[i].value); + } + } + return masterKeyFile; +} + +void lmi_init(const char *provider, const CMPIBroker *cb, const ConfigEntry *provider_config_defaults) +{ + pthread_mutex_lock(&_init_mutex); + // Broker can change between threads _cb = cb; + + // Provider should remain the same + if (_provider != NULL) { + if (strcmp(_provider, provider) != 0) { + lmi_error("lmi_init called twice with different provider (%s -> %s), " + "this shouldn't happen", _provider, provider); + free(_provider); + } else { + pthread_mutex_unlock(&_init_mutex); + return; + } + } + _provider = strdup(provider); + if (_masterKeyFile != NULL) { + g_key_file_free(_masterKeyFile); + } + // Read config only on first call of this function + _masterKeyFile = parse_config(provider, provider_config_defaults); + // We might read different log config, reread it in next _log_debug call + _log_level = _LMI_DEBUG_NONE; + pthread_mutex_unlock(&_init_mutex); +} + +void lmi_init_logging(const char *log_id, const CMPIBroker *cb) +{ + lmi_init(log_id, cb, NULL); } int lmi_log_level(void) @@ -116,6 +286,24 @@ void lmi_set_log_level(int level) void _lmi_debug(int level, const char *file, int line, const char *format, ...) { const char *lvl[] = { "NONE", "ERROR", "WARNING", "INFO", "DEBUG" }; + if (_log_level == _LMI_DEBUG_NONE) { + // Read log level from config or default + _log_level = _LMI_DEBUG_ERROR; // Default + char *level = lmi_read_config("Log", "Level"); + if (level != NULL) { + size_t len = sizeof(lvl) / sizeof(lvl[0]); + for (size_t i = 0; i < len; ++i) { + if (strcasecmp(level, lvl[i]) == 0) { + _log_level = i; + break; + } + } + free(level); + } + + // Read if log to stderr + _log_stderr = lmi_read_config_boolean("Log", "Stderr"); + } if (level > 4) { level = 4; } @@ -123,6 +311,11 @@ void _lmi_debug(int level, const char *file, int line, const char *format, ...) level = 1; } + if (level > _log_level) { + // Do not log this message + return; + } + char *message, *text; va_list args; va_start(args, format); @@ -135,16 +328,28 @@ void _lmi_debug(int level, const char *file, int line, const char *format, ...) rc.rc = CMPI_RC_OK; if (_cb != NULL) { // try to use standard CMPI logging - rc = _cb->eft->trace(_cb, CMPI_LEV_INFO, _log_id, text, NULL); - } - if (_cb == NULL || rc.rc != CMPI_RC_OK) { - // Fallback to stderr - if (level > _log_level) { - free(text); - return; + // CMPI has different severity levels (1=info, 4=fatal) + int severity = CMPI_SEV_INFO; + switch (level) { + case _LMI_DEBUG_DEBUG: + severity = CMPI_DEV_DEBUG; + break; + case _LMI_DEBUG_INFO: + severity = CMPI_SEV_INFO; + break; + case _LMI_DEBUG_WARN: + severity = CMPI_SEV_WARNING; + break; + case _LMI_DEBUG_ERROR: + severity = CMPI_SEV_ERROR; + break; } + rc = CMLogMessage(_cb, severity, _provider, text, NULL); + } + if (_log_stderr || _cb == NULL || rc.rc != CMPI_RC_OK) { + // Fallback to stderr fprintf(stderr, "%s\n", text); } free(text); diff --git a/src/openlmi.conf b/src/openlmi.conf new file mode 100644 index 0000000..8028b20 --- /dev/null +++ b/src/openlmi.conf @@ -0,0 +1,22 @@ +# Sample configuration file for OpenLMI providers + +[CIM] +# To override default CIM Namespace, uncomment the line below. +#Namespace = root/cimv2 + +# To change the CIM class of ComputerSystem, which is associated to many +# software classes, uncomment the line below. +#SystemClassName = Linux_ComputerSystem + +[Log] +# These options modify logging configuration of the main process spawned +# by CIMOM. + +# Level can be set to following values: +# TRACE_VERBOSE, TRACE_INFO, TRACE_WARNING, DEBUG, INFO, WARNING, ERROR, CRITICAL +# It does not have any effect, if file_config option is set. +#Level = ERROR + +# If logging to stderr is desired, set this option to True. This option won't +# apply if file_config option is set. +#Stderr = False diff --git a/src/openlmi.h b/src/openlmi.h index 6ab4158..7d64bd1 100644 --- a/src/openlmi.h +++ b/src/openlmi.h @@ -22,6 +22,13 @@ #define OPENLMI_H #include <cmpidt.h> +#include <stdbool.h> + +typedef struct { + const char *group; + const char *key; + const char *value; +} ConfigEntry; /** * This function returns FQDN (fully qualified domain name) of the machine @@ -43,11 +50,55 @@ const char *lmi_get_system_name(); const char *lmi_get_system_creation_class_name(); /** + * Initialize usage base openlmi tools like configuration file access, + * logging etc. + * + * @note You must call this function prior to getting any configuration option + * or usage of logging. lmi_get_system_creation_class_name requires that this + * function will be called first (SystemCreationClassName is read from config). + * + * This function is reentrant and thread safe, but it should be called always + * with same parameters + * + * @param provider Identification of the CIM provider (must be same as name of the + * configuration file) + * @param cb CMPIBroker + * @param provider_config_defaults Array of default config values for given provider + * NULL if there is no provider-specific configuration + */ +void lmi_init(const char *provider, const CMPIBroker *cb, + const ConfigEntry *provider_config_defaults); + +/** + * Reads string key out of configration files or default configration options. + * + * @param group Configration group + * @param key Configration key + * @return String value of the key or NULL if group/key is not found + */ +char *lmi_read_config(const char *group, const char *key); + +/** + * Reads a boolean value out of configuration files or default configuration + * options. + * + * Values "1", "yes", "true", and "on" are converted to TRUE, others to FALSE + * + * @param group Configration group + * @param key Configration key + * @return Boolean value of the key, false if the key is not in the + * configuration files neither in default options. + */ +bool lmi_read_config_boolean(const char *group, const char *key); + +/** * To use standard CIMOM logging facility, broker must be assigned. Without * calling this function, logging will go to stderr. * - * \p log_id Identification of log messages - * \p cb CMPIBroker + * @deprecated Use lmi_init instead + * + * @param log_id Identification of log messages + * @param cb CMPIBroker */ void lmi_init_logging(const char *log_id, const CMPIBroker *cb); @@ -61,6 +112,9 @@ int lmi_log_level(void); /** * Set logging level * + * @note This method shouldn't be used directly, user setting + * from the configuration file should be honored + * * @param level new logging level */ void lmi_set_log_level(int level); diff --git a/src/power/power.c b/src/power/power.c index fdfeca7..f54e194 100644 --- a/src/power/power.c +++ b/src/power/power.c @@ -34,6 +34,10 @@ #include <upower.h> #endif +const char *provider_name = "powermanagement"; +const ConfigEntry *provider_config_defaults = NULL; + + struct _Power { unsigned int instances; unsigned short requestedPowerState; @@ -67,6 +71,7 @@ Power *_power = NULL; Power *power_new(const CMPIBroker *_cb) { + lmi_init(provider_name, _cb, provider_config_defaults); Power *power = malloc(sizeof(Power)); power->broker = _cb; power->instances = 0; @@ -86,7 +91,8 @@ Power *power_new(const CMPIBroker *_cb) void power_destroy(Power *power) { #ifdef HAS_UPOWER - free(power->up); + g_object_unref(power->up); + power->up = NULL; #endif } diff --git a/src/power/power.h b/src/power/power.h index a52eaef..75b8ea0 100644 --- a/src/power/power.h +++ b/src/power/power.h @@ -22,9 +22,12 @@ #define POWER_H #include <glib.h> +#include <openlmi.h> + +const char *provider_name; +const ConfigEntry *provider_config_defaults; typedef struct _Power Power; -typedef struct _CMPIBroker CMPIBroker; typedef struct _PowerStateChangeJob PowerStateChangeJob; /** diff --git a/src/python/lmi/base/BaseConfiguration.py b/src/python/lmi/base/BaseConfiguration.py index 8790acf..275fc0f 100644 --- a/src/python/lmi/base/BaseConfiguration.py +++ b/src/python/lmi/base/BaseConfiguration.py @@ -72,9 +72,12 @@ class BaseConfiguration(Singleton): There should be only one instance of this class. """ - CONFIG_DIRECTORY_TEMPLATE = '/etc/openlmi/%(provider_prefix)s/' - CONFIG_FILE_PATH_TEMPLATE = \ - CONFIG_DIRECTORY_TEMPLATE + '%(provider_prefix)s.conf' + CONFIG_DIRECTORY_TEMPLATE_TOPLEVEL = '/etc/openlmi/' + CONFIG_DIRECTORY_TEMPLATE_PROVIDER = '/etc/openlmi/%(provider_prefix)s/' + CONFIG_FILE_PATH_TEMPLATE_TOPLEVEL = \ + CONFIG_DIRECTORY_TEMPLATE_TOPLEVEL + 'openlmi.conf' + CONFIG_FILE_PATH_TEMPLATE_PROVIDER = \ + CONFIG_DIRECTORY_TEMPLATE_PROVIDER + '%(provider_prefix)s.conf' PERSISTENT_PATH_TEMPLATE = '/var/lib/openlmi-%(provider_prefix)s/' SETTINGS_DIR = 'settings/' @@ -106,11 +109,17 @@ class BaseConfiguration(Singleton): return cls.DEFAULT_OPTIONS @classmethod - def config_directory(cls): - """ Base directory with configuration settings. """ - return cls.CONFIG_DIRECTORY_TEMPLATE % { + def config_directory_toplevel(cls): + """ Base directory with toplevel configuration settings. """ + return cls.CONFIG_DIRECTORY_TEMPLATE_TOPLEVEL + + @classmethod + def config_directory_provider(cls): + """ Base directory with provider specific configuration settings. """ + return cls.CONFIG_DIRECTORY_TEMPLATE_PROVIDER % { 'provider_prefix' : cls.provider_prefix() } + @classmethod def persistent_path(cls): """ Base directory with persistent settings. """ @@ -118,11 +127,17 @@ class BaseConfiguration(Singleton): 'provider_prefix': cls.provider_prefix() } @classmethod - def config_file_path(cls): - """ File path of configuration file. """ - return cls.CONFIG_FILE_PATH_TEMPLATE % { + def config_file_path_toplevel(cls): + """ File path of toplevel configuration file. """ + return cls.CONFIG_FILE_PATH_TEMPLATE_TOPLEVEL + + @classmethod + def config_file_path_provider(cls): + """ File path of provider specific configuration file. """ + return cls.CONFIG_FILE_PATH_TEMPLATE_PROVIDER % { 'provider_prefix' : cls.provider_prefix() } + @classmethod def mandatory_sections(cls): """ @@ -163,10 +178,11 @@ class BaseConfiguration(Singleton): def load(self): """ - Load configuration from config file path. - The file does not need to exist. + Load configuration from config files. Provider specific options + overrides toplevel openlmi configuration. + The files do not need to exist. """ - self.config.read(self.config_file_path()) + self.config.read([self.config_file_path_toplevel(), self.config_file_path_provider()]) for section in self.mandatory_sections(): if not self.config.has_section(section): self.config.add_section(section) diff --git a/src/python/lmi/providers/cmpi_logging.py b/src/python/lmi/providers/cmpi_logging.py index 1eb9e3a..c1e29c9 100644 --- a/src/python/lmi/providers/cmpi_logging.py +++ b/src/python/lmi/providers/cmpi_logging.py @@ -30,9 +30,9 @@ import os import sys # Custom logging levels -TRACE_WARNING = logging.INFO - 1 -TRACE_INFO = logging.INFO - 2 -TRACE_VERBOSE = logging.DEBUG +TRACE_WARNING = logging.DEBUG - 1 +TRACE_INFO = logging.DEBUG - 2 +TRACE_VERBOSE = logging.DEBUG - 3 # Mapping from level name to its number LOGGING_LEVELS = { @@ -41,10 +41,10 @@ LOGGING_LEVELS = { "warning" : logging.WARNING, "warn" : logging.WARNING, "info" : logging.INFO, + "debug" : logging.DEBUG, "trace_warning" : TRACE_WARNING, "trace_info" : TRACE_INFO, - "trace_verbose" : TRACE_VERBOSE, - "debug" : logging.DEBUG + "trace_verbose" : TRACE_VERBOSE } DEFAULT_LOGGING_CONFIG = { @@ -130,11 +130,13 @@ class CMPILogHandler(logging.Handler): self.cmpi_logger.log_warn(msg) elif record.levelno >= logging.INFO: self.cmpi_logger.log_info(msg) + elif record.levelno >= logging.DEBUG: + self.cmpi_logger.log_debug(msg) elif record.levelno >= TRACE_WARNING: self.cmpi_logger.trace_warn(record.filename, msg) elif record.levelno >= TRACE_INFO: self.cmpi_logger.trace_info(record.filename, msg) - elif record.levelno >= logging.DEBUG: + elif record.levelno >= TRACE_VERBOSE: self.cmpi_logger.trace_verbose(record.filename, msg) class CMPILogger(logging.getLoggerClass()): @@ -184,6 +186,41 @@ class CMPILogger(logging.getLoggerClass()): logging.setLoggerClass(CMPILogger) +def render_value(val): + """ + When logging values, we want to avoid excessively long messages caused + by rendering argument values like lists, dictionaries etc. + Let's shorten these iterable objects to just one or few items. + + :param val: Any value for rendering. + :returns: Representation string of value, possibly shortened. + :rtype: string + """ + if isinstance(val, list): + if len(val) < 2: + return repr(val) + else: + return "[%s, ... (%d more items)]" % ( + render_value(val[0]), len(val) - 1) + elif isinstance(val, dict): + if len(val) < 2: + return repr(val) + else: + key = next(iter(val)) + return '{%s: %s, ... (%d more items)}' % ( + render_value(key), render_value(val[key]), len(val) - 1) + elif isinstance(val, set): + if len(val) < 2: + return repr(val) + else: + return '{%s, ... (%d more items)}' % ( + render_value(val[0]), len(val) - 1) + elif isinstance(val, tuple): + return "(%s%s)" % ( + ", ".join(render_value(i) for i in val), + ", " if len(val) < 2 else '') + return repr(val) + def trace_function_or_method(is_method=False, frame_level=1): """ Factory for function and method decorators. Generated decorators @@ -211,18 +248,6 @@ def trace_function_or_method(is_method=False, frame_level=1): if not inspect.ismethod(func) and not inspect.isfunction(func): raise TypeError("func must be a function") - def _print_value(val): - """ - Used here for printing function arguments. Shortens the output - string, if that would be too long. - """ - if isinstance(val, list): - if len(val) < 2: - return str(val) - else: - return "[%s, ...]" % _print_value(val[0]) - return str(val) - module = func.__module__.split('.')[-1] frm = inspect.currentframe() for _ in range(frame_level): @@ -250,8 +275,8 @@ def trace_function_or_method(is_method=False, frame_level=1): "lineno" : lineno, "action" : "entering", "args" : ", ".join(chain( - (_print_value(a) for a in args), - ( "%s=%s"%(k, _print_value(v)) + (render_value(a) for a in args), + ( "%s=%s"%(k, render_value(v)) for k, v in kwargs.items()))) }) diff --git a/src/realmd/LMI_HostedRealmdServiceProvider.c b/src/realmd/LMI_HostedRealmdServiceProvider.c index 1a9f399..1c06368 100644 --- a/src/realmd/LMI_HostedRealmdServiceProvider.c +++ b/src/realmd/LMI_HostedRealmdServiceProvider.c @@ -8,6 +8,7 @@ static const CMPIBroker* _cb; static void LMI_HostedRealmdServiceInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_HostedRealmdServiceCleanup( diff --git a/src/realmd/LMI_RealmdServiceProvider.c b/src/realmd/LMI_RealmdServiceProvider.c index fa4f834..bd713b8 100644 --- a/src/realmd/LMI_RealmdServiceProvider.c +++ b/src/realmd/LMI_RealmdServiceProvider.c @@ -61,6 +61,7 @@ get_joined_domain(GVariant *provider_props) static void LMI_RealmdServiceInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_RealmdServiceCleanup( diff --git a/src/realmd/rdcp_util.c b/src/realmd/rdcp_util.c index 73ba17b..30cb790 100644 --- a/src/realmd/rdcp_util.c +++ b/src/realmd/rdcp_util.c @@ -3,6 +3,9 @@ #define VERBOSE +const char *provider_name = "realmd"; +const ConfigEntry *provider_config_defaults = NULL; + void print_properties (GVariant *properties, gchar *format, ...) { diff --git a/src/realmd/rdcp_util.h b/src/realmd/rdcp_util.h index aef255a..4936ddb 100644 --- a/src/realmd/rdcp_util.h +++ b/src/realmd/rdcp_util.h @@ -8,6 +8,10 @@ #include <glib.h> #include "rdcp_error.h" +#include "openlmi.h" + +const char *provider_name; +const ConfigEntry *provider_config_defaults; #define ORGID "LMI_Realmd" #define REALMD_SERVICE_NAME "OpenLMI Realmd Service" diff --git a/src/service-dbus/LMI_ServiceProvider.c b/src/service-dbus/LMI_ServiceProvider.c index e4fa3aa..e1329c7 100644 --- a/src/service-dbus/LMI_ServiceProvider.c +++ b/src/service-dbus/LMI_ServiceProvider.c @@ -29,6 +29,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_ServiceInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_ServiceCleanup( @@ -47,10 +48,11 @@ static CMPIStatus LMI_ServiceEnumInstanceNames( { const char *ns = KNameSpace(cop); SList *slist = NULL; + char output[1024]; - slist = service_find_all(); + slist = service_find_all(output, sizeof(output)); if (slist == NULL) { - KReturn2(_cb, ERR_FAILED, "Unable to enumerate instance names of LMI_Service"); + KReturn2(_cb, ERR_FAILED, output); } for (int i = 0; i < slist->cnt; i++) { @@ -103,11 +105,13 @@ static CMPIStatus LMI_ServiceGetInstance( const CMPIObjectPath* cop, const char** properties) { + char output[1024]; + int res; LMI_Service w; LMI_Service_InitFromObjectPath(&w, _cb, cop); Service servicebuf = {0, }; - if (service_get_properties(&servicebuf, w.Name.chars)) { + if ((res = service_get_properties(&servicebuf, w.Name.chars, output, sizeof(output))) == 0) { LMI_Service_Set_Status(&w, servicebuf.svStatus); free(servicebuf.svStatus); LMI_Service_Set_Started(&w, servicebuf.svStarted); @@ -132,8 +136,10 @@ static CMPIStatus LMI_ServiceGetInstance( KReturnInstance(cr, w); KReturn(OK); - } else { + } else if (res == -2) { /* service of that name doesn't exist */ KReturn(ERR_NOT_FOUND); + } else { /* some error occured when getting properties */ + KReturn2(_cb, ERR_FAILED, output); } } diff --git a/src/service-dbus/util/serviceutil.c b/src/service-dbus/util/serviceutil.c index af1e7ff..ac933c5 100644 --- a/src/service-dbus/util/serviceutil.c +++ b/src/service-dbus/util/serviceutil.c @@ -39,6 +39,9 @@ #define SERVICE_INTERFACE "org.freedesktop.systemd1.Service" #define PROPERTY_INTERFACE "org.freedesktop.DBus.Properties" +const char *provider_name = "service"; +const ConfigEntry *provider_config_defaults = NULL; + void service_free_slist(SList *slist) { int i; @@ -54,7 +57,9 @@ void service_free_slist(SList *slist) return; } -SList *service_find_all(void) +SList *service_find_all( + char *output, + int output_len) { GDBusProxy *manager_proxy = NULL; GVariantIter *arr = NULL; @@ -71,6 +76,7 @@ SList *service_find_all(void) manager_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, MANAGER_NAME, MANAGER_OP, MANAGER_INTERFACE, NULL, &error); if (!manager_proxy) { + strncpy(output, error->message, output_len); g_error_free(error); return NULL; } @@ -79,6 +85,7 @@ SList *service_find_all(void) result = g_dbus_proxy_call_sync(manager_proxy, "ListUnitFiles", NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error) { + strncpy(output, error->message, output_len); g_error_free(error); g_object_unref(manager_proxy); return NULL; @@ -89,6 +96,7 @@ SList *service_find_all(void) slist->name = malloc(MAX_SLIST_CNT * sizeof(char *)); if (!slist->name) { free(slist); + g_object_unref(manager_proxy); return NULL; } slist->cnt = 0; @@ -118,7 +126,9 @@ SList *service_find_all(void) int service_get_properties( Service *svc, - const char *service) + const char *service, + char *output, + int output_len) { GDBusProxy *manager_proxy = NULL; GDBusProxy *proxy = NULL; @@ -128,14 +138,23 @@ int service_get_properties( GError *error = NULL; gchar *fragment_path = NULL, *unit_file_state = NULL; gchar *unit, *value_str; + char found = 0; + + if (!service) { + strncpy(output, "Invalid service name", output_len); + return -1; + } + + svc->svName = strdup(service); + if (!svc->svName) { + strncpy(output, "Insufficient memory", output_len); + return -1; + } #if !defined(GLIB_VERSION_2_36) g_type_init(); #endif - svc->svName = strdup(service); - if (!svc->svName) return 0; - manager_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, MANAGER_NAME, MANAGER_OP, MANAGER_INTERFACE, NULL, &error); if (!manager_proxy) goto error; @@ -149,6 +168,7 @@ int service_get_properties( g_variant_get(result, "(a(ss))", &arr); while (g_variant_iter_loop(arr, "(ss)", &fragment_path, &unit_file_state)) { if (strstr(fragment_path, service) && strcmp(strstr(fragment_path, service), service) == 0) { + found = 1; if (strncmp(unit_file_state, "enabled", 7) == 0) svc->svEnabledDefault = ENABLED; if (strncmp(unit_file_state, "disabled", 8) == 0) @@ -158,6 +178,12 @@ int service_get_properties( g_variant_iter_free(arr); arr = NULL; + if (!found) { + free(svc->svName); + g_object_unref(manager_proxy); + return -2; + } + error = NULL; result = g_dbus_proxy_call_sync(manager_proxy, "LoadUnit", g_variant_new("(s)", service), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); @@ -224,16 +250,19 @@ int service_get_properties( if (!svc->svStatus) goto error; g_object_unref(proxy); - return 1; + return 0; error: if (svc->svName) free(svc->svName); - if (error) g_error_free(error); + if (error) { + strncpy(output, error->message, output_len); + g_error_free(error); + } if (manager_proxy) g_object_unref(manager_proxy); if (proxy) g_object_unref(proxy); if (svc->svCaption) free(svc->svCaption); - return 0; + return -1; } unsigned int service_operation( @@ -247,6 +276,16 @@ unsigned int service_operation( GError *error = NULL; GVariantBuilder *builder; + if (!service) { + strncpy(output, "Invalid service name", output_len); + return -1; + } + + if (!method) { + strncpy(output, "Invalid method name", output_len); + return -1; + } + #if !defined(GLIB_VERSION_2_36) g_type_init(); #endif @@ -254,6 +293,7 @@ unsigned int service_operation( manager_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_NONE, NULL, MANAGER_NAME, MANAGER_OP, MANAGER_INTERFACE, NULL, &error); if (!manager_proxy) { + strncpy(output, error->message, output_len); g_error_free(error); return -1; } @@ -270,6 +310,7 @@ unsigned int service_operation( G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); } if (error) { + strncpy(output, error->message, output_len); g_error_free(error); g_object_unref(manager_proxy); return -1; @@ -278,6 +319,7 @@ unsigned int service_operation( result = g_dbus_proxy_call_sync(manager_proxy, method, g_variant_new("(ss)", service, "replace"), G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); if (error) { + strncpy(output, error->message, output_len); g_error_free(error); g_object_unref(manager_proxy); return -1; diff --git a/src/service-dbus/util/serviceutil.h b/src/service-dbus/util/serviceutil.h index d1ed1be..020cfb7 100644 --- a/src/service-dbus/util/serviceutil.h +++ b/src/service-dbus/util/serviceutil.h @@ -23,9 +23,13 @@ #define SERVICEUTIL_H #include <stdio.h> +#include "openlmi.h" #define ARRAY_SIZE(name) (sizeof(name) / sizeof(name[0])) +const char *provider_name; +const ConfigEntry *provider_config_defaults; + enum OperationalStatus {OS_UNKNOWN = 0, OS_OK = 2, OS_ERROR = 6, OS_STARTING = 8, OS_STOPPING = 9, OS_STOPPED = 10, OS_COMPLETED = 17}; enum ServiceEnabledDefault {ENABLED = 2, DISABLED = 3, NOT_APPLICABLE = 5}; @@ -51,9 +55,9 @@ typedef struct _Service Service; typedef struct _SList SList; void service_free_slist(SList *slist); -SList *service_find_all(void); +SList *service_find_all(char *output, int output_len); -int service_get_properties(Service *svc, const char *service); +int service_get_properties(Service *svc, const char *service, char *output, int output_len); unsigned int service_operation(const char *service, const char *method, char *output, int output_len); diff --git a/src/service/LMI_ServiceProvider.c b/src/service/LMI_ServiceProvider.c index 7c8ffdb..9e15eed 100644 --- a/src/service/LMI_ServiceProvider.c +++ b/src/service/LMI_ServiceProvider.c @@ -29,6 +29,7 @@ static const CMPIBroker* _cb = NULL; static void LMI_ServiceInitialize() { + lmi_init(provider_name, _cb, provider_config_defaults); } static CMPIStatus LMI_ServiceCleanup( diff --git a/src/service/util/serviceutil.c b/src/service/util/serviceutil.c index bb8a472..72fe51d 100644 --- a/src/service/util/serviceutil.c +++ b/src/service/util/serviceutil.c @@ -36,6 +36,9 @@ char *suscript = "/usr/libexec/serviceutil.sh"; char *sdscript = "/usr/libexec/servicedisc.sh"; +const char *provider_name = "service"; +const ConfigEntry *provider_config_defaults = NULL; + typedef struct { FILE *fp; FILE *fp2; diff --git a/src/service/util/serviceutil.h b/src/service/util/serviceutil.h index 055f43f..776a3c8 100644 --- a/src/service/util/serviceutil.h +++ b/src/service/util/serviceutil.h @@ -26,6 +26,9 @@ #define ARRAY_SIZE(name) (sizeof(name) / sizeof(name[0])) +const char *provider_name; +const ConfigEntry *provider_config_defaults; + enum ServiceEnabledDefault { ENABLED = 2, DISABLED = 3, NOT_APPICABLE = 5}; struct _Service { diff --git a/src/software/config/software.conf b/src/software/config/software.conf index 0332ecd..91a809d 100644 --- a/src/software/config/software.conf +++ b/src/software/config/software.conf @@ -42,7 +42,7 @@ # by CIMOM. # Level can be set to following values: -# DEBUG, TRACE_INFO, TRACE_WARNING, INFO, WARNING, ERROR, CRITICAL +# TRACE_VERBOSE, TRACE_INFO, TRACE_WARNING, DEBUG, INFO, WARNING, ERROR, CRITICAL # It does not have any effect, if file_config option is set. #Level = ERROR diff --git a/src/software/lmi/software/yumdb/__init__.py b/src/software/lmi/software/yumdb/__init__.py index afd3c1c..6992c29 100644 --- a/src/software/lmi/software/yumdb/__init__.py +++ b/src/software/lmi/software/yumdb/__init__.py @@ -259,8 +259,7 @@ class YumDB(singletonmixin.Singleton): LOG().debug("[jobid=%d] received desired reply", job.jobid) with self._reply_lock: self._expected.remove(job.jobid) - if len(self._expected): - self._reply_cond.notify() + self._reply_cond.notifyAll() return jobout else: LOG().info("[jobid=%d] received reply for another thread" @@ -302,6 +301,7 @@ class YumDB(singletonmixin.Singleton): except ValueError: LOG().warn("[jobid=%d] reply not in expected list", job.jobid) + self._reply_cond.notifyAll() return self._replies.pop(job.jobid) elif job.jobid not in self._expected: # process terminated, resending job diff --git a/src/software/lmi/software/yumdb/jobmanager.py b/src/software/lmi/software/yumdb/jobmanager.py index 6b0b854..1b986bd 100644 --- a/src/software/lmi/software/yumdb/jobmanager.py +++ b/src/software/lmi/software/yumdb/jobmanager.py @@ -69,7 +69,7 @@ def job_handler(job_from_target=True): it an instance of YumJob. The method is then called with "job" argument instead of "target". """ - logged = cmpi_logging.trace_method(method) + logged = cmpi_logging.trace_method(method, frame_level=2) def _new_func(self, *args, **kwargs): """Wrapper around method.""" @@ -294,7 +294,8 @@ class JobManager(threading.Thread): LOG.exception("control job %s failed", job) job.finish(result, data) LOG.debug("sending reply for %s: (%s, %s)", job, - job.ResultNames[job.result], job.result_data) + job.ResultNames[job.result], + cmpi_logging.render_value(job.result_data)) self._queue_out.put(job) else: if job is None: @@ -508,7 +509,8 @@ class JobManager(threading.Thread): ind.send(True) else: LOG.debug("sending reply for %s: (%s, %s)", job, - job.ResultNames[job.result], job.result_data) + job.ResultNames[job.result], + cmpi_logging.render_value(job.result_data)) self._queue_out.put(job) return job |