diff options
author | Peter Schiffer <pschiffe@redhat.com> | 2014-01-13 17:02:06 +0100 |
---|---|---|
committer | Peter Schiffer <pschiffe@redhat.com> | 2014-01-14 13:56:49 +0100 |
commit | 00d6546132d71931951c60c7572f27799893527e (patch) | |
tree | ad11852481614c4fd628327d864f0d0ded34bf9f /src/hardware | |
parent | 72834a3621e8e103a763a1810b004d425164461f (diff) | |
download | openlmi-providers-00d6546132d71931951c60c7572f27799893527e.tar.gz openlmi-providers-00d6546132d71931951c60c7572f27799893527e.tar.xz openlmi-providers-00d6546132d71931951c60c7572f27799893527e.zip |
Hardware: added LMI_DiskDriveATAPortProvider
New provider:
* LMI_DiskDriveATAPortProvider
Diffstat (limited to 'src/hardware')
-rw-r--r-- | src/hardware/LMI_DiskDriveATAPortProvider.c | 368 | ||||
-rw-r--r-- | src/hardware/LMI_Hardware.h | 1 | ||||
-rw-r--r-- | src/hardware/smartctl.c | 38 | ||||
-rw-r--r-- | src/hardware/smartctl.h | 24 |
4 files changed, 414 insertions, 17 deletions
diff --git a/src/hardware/LMI_DiskDriveATAPortProvider.c b/src/hardware/LMI_DiskDriveATAPortProvider.c new file mode 100644 index 0000000..122b3aa --- /dev/null +++ b/src/hardware/LMI_DiskDriveATAPortProvider.c @@ -0,0 +1,368 @@ +/* + * Copyright (C) 2014 Red Hat, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Peter Schiffer <pschiffe@redhat.com> + */ + +#include <konkret/konkret.h> +#include "LMI_DiskDriveATAPort.h" +#include "LMI_Hardware.h" +#include "globals.h" +#include "smartctl.h" +#include "lsblk.h" + +CMPIUint16 get_port_type(const char *port_type); + +static const CMPIBroker* _cb = NULL; + +static void LMI_DiskDriveATAPortInitialize(const CMPIContext *ctx) +{ + lmi_init(provider_name, _cb, ctx, provider_config_defaults); +} + +static CMPIStatus LMI_DiskDriveATAPortCleanup( + CMPIInstanceMI* mi, + const CMPIContext* cc, + CMPIBoolean term) +{ + CMReturn(CMPI_RC_OK); +} + +static CMPIStatus LMI_DiskDriveATAPortEnumInstanceNames( + CMPIInstanceMI* mi, + const CMPIContext* cc, + const CMPIResult* cr, + const CMPIObjectPath* cop) +{ + return KDefaultEnumerateInstanceNames( + _cb, mi, cc, cr, cop); +} + +static CMPIStatus LMI_DiskDriveATAPortEnumInstances( + CMPIInstanceMI* mi, + const CMPIContext* cc, + const CMPIResult* cr, + const CMPIObjectPath* cop, + const char** properties) +{ + LMI_DiskDriveATAPort lmi_hdd_ata_port; + const char *ns = KNameSpace(cop); + unsigned i, j; + char instance_id[INSTANCE_ID_LEN], name[ELEMENT_NAME_LEN]; + SmartctlHdd *smtcl_hdds = NULL; + unsigned smtcl_hdds_nb = 0; + LsblkHdd *lsblk_hdds = NULL; + unsigned lsblk_hdds_nb = 0; + + if (lsblk_get_hdds(&lsblk_hdds, &lsblk_hdds_nb) != 0 || lsblk_hdds_nb < 1) { + goto done; + } + if (smartctl_get_hdds(&smtcl_hdds, &smtcl_hdds_nb) != 0 || smtcl_hdds_nb < 1) { + smartctl_free_hdds(&smtcl_hdds, &smtcl_hdds_nb); + } + + for (i = 0; i < lsblk_hdds_nb; i++) { + /* use only disk devices from lsblk */ + if (strcmp(lsblk_hdds[i].type, "disk") != 0) { + continue; + } + + LMI_DiskDriveATAPort_Init(&lmi_hdd_ata_port, _cb, ns); + + LMI_DiskDriveATAPort_Set_SystemCreationClassName(&lmi_hdd_ata_port, + get_system_creation_class_name()); + LMI_DiskDriveATAPort_Set_SystemName(&lmi_hdd_ata_port, get_system_name()); + LMI_DiskDriveATAPort_Set_CreationClassName(&lmi_hdd_ata_port, + ORGID "_" DISK_DRIVE_ATA_PORT_CLASS_NAME); + LMI_DiskDriveATAPort_Set_Caption(&lmi_hdd_ata_port, + "Disk Drive ATA Port"); + LMI_DiskDriveATAPort_Set_Description(&lmi_hdd_ata_port, + "This object represents ATA Port of disk drive in system."); + LMI_DiskDriveATAPort_Set_UsageRestriction(&lmi_hdd_ata_port, + LMI_DiskDriveATAPort_UsageRestriction_Front_end_only); + + snprintf(name, ELEMENT_NAME_LEN, + "%s " DISK_DRIVE_ATA_PORT_CLASS_NAME, + lsblk_hdds[i].name); + snprintf(instance_id, INSTANCE_ID_LEN, + ORGID ":" ORGID "_" DISK_DRIVE_ATA_PORT_CLASS_NAME ":%s", + name); + + LMI_DiskDriveATAPort_Set_DeviceID(&lmi_hdd_ata_port, name); + LMI_DiskDriveATAPort_Set_Name(&lmi_hdd_ata_port, name); + LMI_DiskDriveATAPort_Set_ElementName(&lmi_hdd_ata_port, name); + LMI_DiskDriveATAPort_Set_InstanceID(&lmi_hdd_ata_port, instance_id); + + /* check for smartctl output */ + for (j = 0; j < smtcl_hdds_nb; j++) { + if (strcmp(smtcl_hdds[j].dev_path, lsblk_hdds[i].name) == 0) { + LMI_DiskDriveATAPort_Set_PortType(&lmi_hdd_ata_port, + get_port_type(smtcl_hdds[j].port_type)); + + if (smtcl_hdds[j].max_port_speed) { + LMI_DiskDriveATAPort_Set_MaxSpeed(&lmi_hdd_ata_port, + smtcl_hdds[j].max_port_speed); + } + if (smtcl_hdds[j].port_speed) { + LMI_DiskDriveATAPort_Set_Speed(&lmi_hdd_ata_port, + smtcl_hdds[j].port_speed); + } + + break; + } + } + + KReturnInstance(cr, lmi_hdd_ata_port); + } + +done: + smartctl_free_hdds(&smtcl_hdds, &smtcl_hdds_nb); + lsblk_free_hdds(&lsblk_hdds, &lsblk_hdds_nb); + + CMReturn(CMPI_RC_OK); +} + +static CMPIStatus LMI_DiskDriveATAPortGetInstance( + CMPIInstanceMI* mi, + const CMPIContext* cc, + const CMPIResult* cr, + const CMPIObjectPath* cop, + const char** properties) +{ + return KDefaultGetInstance( + _cb, mi, cc, cr, cop, properties); +} + +static CMPIStatus LMI_DiskDriveATAPortCreateInstance( + CMPIInstanceMI* mi, + const CMPIContext* cc, + const CMPIResult* cr, + const CMPIObjectPath* cop, + const CMPIInstance* ci) +{ + CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); +} + +static CMPIStatus LMI_DiskDriveATAPortModifyInstance( + CMPIInstanceMI* mi, + const CMPIContext* cc, + const CMPIResult* cr, + const CMPIObjectPath* cop, + const CMPIInstance* ci, + const char** properties) +{ + CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); +} + +static CMPIStatus LMI_DiskDriveATAPortDeleteInstance( + CMPIInstanceMI* mi, + const CMPIContext* cc, + const CMPIResult* cr, + const CMPIObjectPath* cop) +{ + CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); +} + +static CMPIStatus LMI_DiskDriveATAPortExecQuery( + CMPIInstanceMI* mi, + const CMPIContext* cc, + const CMPIResult* cr, + const CMPIObjectPath* cop, + const char* lang, + const char* query) +{ + CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); +} + +CMInstanceMIStub( + LMI_DiskDriveATAPort, + LMI_DiskDriveATAPort, + _cb, + LMI_DiskDriveATAPortInitialize(ctx)) + +static CMPIStatus LMI_DiskDriveATAPortMethodCleanup( + CMPIMethodMI* mi, + const CMPIContext* cc, + CMPIBoolean term) +{ + CMReturn(CMPI_RC_OK); +} + +static CMPIStatus LMI_DiskDriveATAPortInvokeMethod( + CMPIMethodMI* mi, + const CMPIContext* cc, + const CMPIResult* cr, + const CMPIObjectPath* cop, + const char* meth, + const CMPIArgs* in, + CMPIArgs* out) +{ + return LMI_DiskDriveATAPort_DispatchMethod( + _cb, mi, cc, cr, cop, meth, in, out); +} + +CMMethodMIStub( + LMI_DiskDriveATAPort, + LMI_DiskDriveATAPort, + _cb, + LMI_DiskDriveATAPortInitialize(ctx)) + +KUint32 LMI_DiskDriveATAPort_RequestStateChange( + const CMPIBroker* cb, + CMPIMethodMI* mi, + const CMPIContext* context, + const LMI_DiskDriveATAPortRef* self, + const KUint16* RequestedState, + KRef* Job, + const KDateTime* TimeoutPeriod, + CMPIStatus* status) +{ + KUint32 result = KUINT32_INIT; + + KSetStatus(status, ERR_NOT_SUPPORTED); + return result; +} + +KUint32 LMI_DiskDriveATAPort_SetPowerState( + const CMPIBroker* cb, + CMPIMethodMI* mi, + const CMPIContext* context, + const LMI_DiskDriveATAPortRef* self, + const KUint16* PowerState, + const KDateTime* Time, + CMPIStatus* status) +{ + KUint32 result = KUINT32_INIT; + + KSetStatus(status, ERR_NOT_SUPPORTED); + return result; +} + +KUint32 LMI_DiskDriveATAPort_Reset( + const CMPIBroker* cb, + CMPIMethodMI* mi, + const CMPIContext* context, + const LMI_DiskDriveATAPortRef* self, + CMPIStatus* status) +{ + KUint32 result = KUINT32_INIT; + + KSetStatus(status, ERR_NOT_SUPPORTED); + return result; +} + +KUint32 LMI_DiskDriveATAPort_EnableDevice( + const CMPIBroker* cb, + CMPIMethodMI* mi, + const CMPIContext* context, + const LMI_DiskDriveATAPortRef* self, + const KBoolean* Enabled, + CMPIStatus* status) +{ + KUint32 result = KUINT32_INIT; + + KSetStatus(status, ERR_NOT_SUPPORTED); + return result; +} + +KUint32 LMI_DiskDriveATAPort_OnlineDevice( + const CMPIBroker* cb, + CMPIMethodMI* mi, + const CMPIContext* context, + const LMI_DiskDriveATAPortRef* self, + const KBoolean* Online, + CMPIStatus* status) +{ + KUint32 result = KUINT32_INIT; + + KSetStatus(status, ERR_NOT_SUPPORTED); + return result; +} + +KUint32 LMI_DiskDriveATAPort_QuiesceDevice( + const CMPIBroker* cb, + CMPIMethodMI* mi, + const CMPIContext* context, + const LMI_DiskDriveATAPortRef* self, + const KBoolean* Quiesce, + CMPIStatus* status) +{ + KUint32 result = KUINT32_INIT; + + KSetStatus(status, ERR_NOT_SUPPORTED); + return result; +} + +KUint32 LMI_DiskDriveATAPort_SaveProperties( + const CMPIBroker* cb, + CMPIMethodMI* mi, + const CMPIContext* context, + const LMI_DiskDriveATAPortRef* self, + CMPIStatus* status) +{ + KUint32 result = KUINT32_INIT; + + KSetStatus(status, ERR_NOT_SUPPORTED); + return result; +} + +KUint32 LMI_DiskDriveATAPort_RestoreProperties( + const CMPIBroker* cb, + CMPIMethodMI* mi, + const CMPIContext* context, + const LMI_DiskDriveATAPortRef* self, + CMPIStatus* status) +{ + KUint32 result = KUINT32_INIT; + + KSetStatus(status, ERR_NOT_SUPPORTED); + return result; +} + +/* + * Get CIM port type according to smartctl port type. + * @param port_type from smartctl + * @return CIM id of port type + */ +CMPIUint16 get_port_type(const char *port_type) +{ + static struct { + unsigned short cim_val; /* CIM value */ + char *port_type; /* smartctl port type */ + } values[] = { + {LMI_DiskDriveATAPort_PortType_Unknown, "Unknown"}, + {LMI_DiskDriveATAPort_PortType_ATA, "ATA"}, + {LMI_DiskDriveATAPort_PortType_SATA, "SATA"}, + {LMI_DiskDriveATAPort_PortType_SATA2, "SATA 2"}, + }; + + size_t i, val_length = sizeof(values) / sizeof(values[0]); + + for (i = 0; i < val_length; i++) { + if (strcmp(port_type, values[i].port_type) == 0) { + return values[i].cim_val; + } + } + + return LMI_DiskDriveATAPort_PortType_Other; +} + +KONKRET_REGISTRATION( + "root/cimv2", + "LMI_DiskDriveATAPort", + "LMI_DiskDriveATAPort", + "instance method") diff --git a/src/hardware/LMI_Hardware.h b/src/hardware/LMI_Hardware.h index e9873f1..9d4bd1e 100644 --- a/src/hardware/LMI_Hardware.h +++ b/src/hardware/LMI_Hardware.h @@ -50,5 +50,6 @@ const char *provider_name; #define DISK_DRIVE_CLASS_NAME "DiskDrive" #define DISK_DRIVE_SW_IDENTITY_CLASS_NAME "DiskDriveSoftwareIdentity" #define DISK_DRIVE_ATA_PROTO_ENDPOINT_CLASS_NAME "ATAProtocolEndpoint" +#define DISK_DRIVE_ATA_PORT_CLASS_NAME "DiskDriveATAPort" #endif /* LMI_HARDWARE_H_ */ diff --git a/src/hardware/smartctl.c b/src/hardware/smartctl.c index 874475a..7dccb9a 100644 --- a/src/hardware/smartctl.c +++ b/src/hardware/smartctl.c @@ -34,8 +34,10 @@ void init_smctlhdd_struct(SmartctlHdd *hdd) hdd->name = NULL; hdd->smart_status = NULL; hdd->firmware = NULL; + hdd->port_type = NULL; hdd->form_factor = 0; hdd->port_speed = 0; + hdd->max_port_speed = 0; hdd->rpm = 0xffffffff; } @@ -88,6 +90,11 @@ short check_smctlhdd_attributes(SmartctlHdd *hdd) goto done; } } + if (!hdd->port_type) { + if (!(hdd->port_type = strdup("Unknown"))) { + goto done; + } + } ret = 0; @@ -290,15 +297,32 @@ short smartctl_get_hdds(SmartctlHdd **hdds, unsigned *hdds_nb) buf = NULL; continue; } - /* Port Speed */ - buf = copy_string_part_after_delim(buffer[i], " (current: "); + /* Port Type, Max and Current Speed */ + buf = copy_string_part_after_delim(buffer[i], "SATA Version is:"); if (buf) { - float speed; - sscanf(buf, "%f", &speed); + if ((*hdds)[curr_hdd].dev_basename[0] == 's') { + if (strncmp(buf, "SATA 2", 6) == 0) { + (*hdds)[curr_hdd].port_type = strdup("SATA 2"); + } else if (strncmp(buf, "SATA", 4) == 0) { + (*hdds)[curr_hdd].port_type = strdup("SATA"); + } + } else if ((*hdds)[curr_hdd].dev_basename[0] == 'h') { + (*hdds)[curr_hdd].port_type = strdup("ATA"); + } + + char *buf2 = strchr(buf, ','); + if (buf2 && strlen(buf2) > 20) { + float max_speed, curr_speed; + /* skip ", " */ + buf2 += 2; + sscanf(buf2, "%f %*s %*s %f", &max_speed, &curr_speed); + /* Gb/s -> b/s */ + (*hdds)[curr_hdd].port_speed = round(curr_speed * 1000000000); + (*hdds)[curr_hdd].max_port_speed = round(max_speed * 1000000000); + } + free(buf); buf = NULL; - /* Gb/s -> b/s */ - (*hdds)[curr_hdd].port_speed = round(speed * 1073741824); continue; } /* RPM */ @@ -357,6 +381,8 @@ void smartctl_free_hdds(SmartctlHdd **hdds, unsigned *hdds_nb) (*hdds)[i].smart_status = NULL; free((*hdds)[i].firmware); (*hdds)[i].firmware = NULL; + free((*hdds)[i].port_type); + (*hdds)[i].port_type = NULL; } free(*hdds); } diff --git a/src/hardware/smartctl.h b/src/hardware/smartctl.h index 4f3eadb..4de75d0 100644 --- a/src/hardware/smartctl.h +++ b/src/hardware/smartctl.h @@ -34,17 +34,19 @@ /* HDD from smartctl. */ typedef struct _SmartctlHdd { - char *dev_path; /* /dev/path */ - char *dev_basename; /* basename of /dev/path */ - char *manufacturer; /* Manufacturer */ - char *model; /* Model */ - char *serial_number; /* Serial Number */ - char *name; /* Name */ - char *smart_status; /* SMART status */ - char *firmware; /* Firmware version */ - unsigned short form_factor; /* Form Factor */ - unsigned long port_speed; /* Port Speed in b/s */ - unsigned rpm; /* RPM of drive */ + char *dev_path; /* /dev/path */ + char *dev_basename; /* basename of /dev/path */ + char *manufacturer; /* Manufacturer */ + char *model; /* Model */ + char *serial_number; /* Serial Number */ + char *name; /* Name */ + char *smart_status; /* SMART status */ + char *firmware; /* Firmware version */ + char *port_type; /* Port Type: ATA, SATA or SATA 2 */ + unsigned short form_factor; /* Form Factor */ + unsigned long port_speed; /* Current Port Speed in b/s */ + unsigned long max_port_speed; /* Max Port Speed in b/s */ + unsigned rpm; /* RPM of drive */ } SmartctlHdd; /* |