summaryrefslogtreecommitdiffstats
path: root/src/hardware
diff options
context:
space:
mode:
authorPeter Schiffer <pschiffe@redhat.com>2014-01-13 17:02:06 +0100
committerPeter Schiffer <pschiffe@redhat.com>2014-01-14 13:56:49 +0100
commit00d6546132d71931951c60c7572f27799893527e (patch)
treead11852481614c4fd628327d864f0d0ded34bf9f /src/hardware
parent72834a3621e8e103a763a1810b004d425164461f (diff)
downloadopenlmi-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.c368
-rw-r--r--src/hardware/LMI_Hardware.h1
-rw-r--r--src/hardware/smartctl.c38
-rw-r--r--src/hardware/smartctl.h24
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;
/*