summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPeter Schiffer <pschiffe@redhat.com>2013-10-31 16:43:54 +0100
committerPeter Schiffer <pschiffe@redhat.com>2013-11-05 15:16:07 +0100
commit268cc0805bb2b580aa6734656fd698bf54523d6c (patch)
treecdcf9ad4a911a03171d33a5cee565da6c3a03272
parent4f6220c7c311165fcdf943268fc0a87788e87fb5 (diff)
downloadopenlmi-providers-268cc0805bb2b580aa6734656fd698bf54523d6c.tar.gz
openlmi-providers-268cc0805bb2b580aa6734656fd698bf54523d6c.tar.xz
openlmi-providers-268cc0805bb2b580aa6734656fd698bf54523d6c.zip
Hardware: Added Physical Disk Provider
New Provider: * LMI_DiskPhysicalPackage
-rw-r--r--mof/60_LMI_Hardware.mof9
-rw-r--r--openlmi-providers.spec8
-rw-r--r--src/hardware/CMakeLists.txt1
-rw-r--r--src/hardware/LMI_DiskPhysicalPackageProvider.c206
-rw-r--r--src/hardware/LMI_Hardware.h1
-rw-r--r--src/hardware/dmidecode.h2
-rw-r--r--src/hardware/smartctl.c270
-rw-r--r--src/hardware/smartctl.h60
-rw-r--r--src/hardware/sysfs.c12
-rw-r--r--src/hardware/sysfs.h16
10 files changed, 570 insertions, 15 deletions
diff --git a/mof/60_LMI_Hardware.mof b/mof/60_LMI_Hardware.mof
index 74e1ee5..adef642 100644
--- a/mof/60_LMI_Hardware.mof
+++ b/mof/60_LMI_Hardware.mof
@@ -449,3 +449,12 @@ class LMI_PCIBridgeSystemDevice: CIM_SystemDevice
[Override("PartComponent")]
LMI_PCIBridge REF PartComponent;
};
+
+/******************************************************************************
+ * Disks
+ */
+
+[ Version("0.5.0"), Provider("cmpi:cmpiLMI_DiskPhysicalPackage") ]
+class LMI_DiskPhysicalPackage: CIM_PhysicalPackage
+{
+};
diff --git a/openlmi-providers.spec b/openlmi-providers.spec
index 34e4e29..d4eeffc 100644
--- a/openlmi-providers.spec
+++ b/openlmi-providers.spec
@@ -3,7 +3,7 @@
Name: openlmi-providers
Version: 0.4.1
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: Set of basic CIM providers
License: LGPLv2+
@@ -144,6 +144,7 @@ Requires: %{name}%{?_isa} = %{version}-%{release}
Requires: dmidecode
%endif
Requires: util-linux
+Requires: smartmontools
%description -n openlmi-hardware
%{summary}.
@@ -885,7 +886,10 @@ if [ "$1" -eq 0 ]; then
fi >> %logfile 2>&1
%changelog
-* Mon Nov 04 2013 Radek Novacek <rnovacek@redhat.com> 0.4.1-3
+* Tue Nov 05 2013 Peter Schiffer <pschiffe@redhat.com> 0.4.1-2
+- Added dependency on smartmontools to hardware subpackage
+
+* Mon Nov 04 2013 Radek Novacek <rnovacek@redhat.com> 0.4.1-1
- Version 0.4.1
- Add powermanagement and hardware providers documentation
- Require cim-schema
diff --git a/src/hardware/CMakeLists.txt b/src/hardware/CMakeLists.txt
index 8ccf649..d0272a0 100644
--- a/src/hardware/CMakeLists.txt
+++ b/src/hardware/CMakeLists.txt
@@ -10,6 +10,7 @@ set(provider_SRCS
procfs.c
sysfs.c
PCIDev.c
+ smartctl.c
)
konkretcmpi_generate(${MOF}
diff --git a/src/hardware/LMI_DiskPhysicalPackageProvider.c b/src/hardware/LMI_DiskPhysicalPackageProvider.c
new file mode 100644
index 0000000..a2945f1
--- /dev/null
+++ b/src/hardware/LMI_DiskPhysicalPackageProvider.c
@@ -0,0 +1,206 @@
+/*
+ * Copyright (C) 2013 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_DiskPhysicalPackage.h"
+#include "LMI_Hardware.h"
+#include "globals.h"
+#include "smartctl.h"
+
+static const CMPIBroker* _cb = NULL;
+
+static void LMI_DiskPhysicalPackageInitialize()
+{
+}
+
+static CMPIStatus LMI_DiskPhysicalPackageCleanup(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ CMPIBoolean term)
+{
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_DiskPhysicalPackageEnumInstanceNames(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop)
+{
+ return KDefaultEnumerateInstanceNames(
+ _cb, mi, cc, cr, cop);
+}
+
+static CMPIStatus LMI_DiskPhysicalPackageEnumInstances(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char** properties)
+{
+ LMI_DiskPhysicalPackage lmi_hdd;
+ const char *ns = KNameSpace(cop);
+ unsigned i;
+ char instance_id[INSTANCE_ID_LEN];
+ SmartctlHdd *smtcl_hdds = NULL;
+ unsigned smtcl_hdds_nb = 0;
+
+ if (smartctl_get_hdds(&smtcl_hdds, &smtcl_hdds_nb) != 0 || smtcl_hdds_nb < 1) {
+ goto done;
+ }
+
+ for (i = 0; i < smtcl_hdds_nb; i++) {
+ LMI_DiskPhysicalPackage_Init(&lmi_hdd, _cb, ns);
+
+ LMI_DiskPhysicalPackage_Set_CreationClassName(&lmi_hdd,
+ ORGID "_" DISK_PHYS_PKG_CLASS_NAME);
+ LMI_DiskPhysicalPackage_Set_PackageType(&lmi_hdd,
+ LMI_DiskPhysicalPackage_PackageType_Storage_Media_Package_e_g___Disk_or_Tape_Drive);
+
+ snprintf(instance_id, INSTANCE_ID_LEN,
+ ORGID ":" ORGID "_" DISK_PHYS_PKG_CLASS_NAME ":%s",
+ smtcl_hdds[i].serial_number);
+
+ LMI_DiskPhysicalPackage_Set_Tag(&lmi_hdd, smtcl_hdds[i].serial_number);
+ LMI_DiskPhysicalPackage_Set_Manufacturer(&lmi_hdd,
+ smtcl_hdds[i].manufacturer);
+ LMI_DiskPhysicalPackage_Set_Model(&lmi_hdd, smtcl_hdds[i].model);
+ LMI_DiskPhysicalPackage_Set_SerialNumber(&lmi_hdd,
+ smtcl_hdds[i].serial_number);
+ LMI_DiskPhysicalPackage_Set_Caption(&lmi_hdd, "Physical Disk Package");
+ LMI_DiskPhysicalPackage_Set_Description(&lmi_hdd,
+ "This object represents one physical disk package in system.");
+ LMI_DiskPhysicalPackage_Set_Name(&lmi_hdd, smtcl_hdds[i].name);
+ LMI_DiskPhysicalPackage_Set_ElementName(&lmi_hdd, smtcl_hdds[i].name);
+ LMI_DiskPhysicalPackage_Set_InstanceID(&lmi_hdd, instance_id);
+
+ KReturnInstance(cr, lmi_hdd);
+ }
+
+done:
+ smartctl_free_hdds(&smtcl_hdds, &smtcl_hdds_nb);
+
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_DiskPhysicalPackageGetInstance(
+ 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_DiskPhysicalPackageCreateInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const CMPIInstance* ci)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_DiskPhysicalPackageModifyInstance(
+ 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_DiskPhysicalPackageDeleteInstance(
+ CMPIInstanceMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop)
+{
+ CMReturn(CMPI_RC_ERR_NOT_SUPPORTED);
+}
+
+static CMPIStatus LMI_DiskPhysicalPackageExecQuery(
+ 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_DiskPhysicalPackage,
+ LMI_DiskPhysicalPackage,
+ _cb,
+ LMI_DiskPhysicalPackageInitialize())
+
+static CMPIStatus LMI_DiskPhysicalPackageMethodCleanup(
+ CMPIMethodMI* mi,
+ const CMPIContext* cc,
+ CMPIBoolean term)
+{
+ CMReturn(CMPI_RC_OK);
+}
+
+static CMPIStatus LMI_DiskPhysicalPackageInvokeMethod(
+ CMPIMethodMI* mi,
+ const CMPIContext* cc,
+ const CMPIResult* cr,
+ const CMPIObjectPath* cop,
+ const char* meth,
+ const CMPIArgs* in,
+ CMPIArgs* out)
+{
+ return LMI_DiskPhysicalPackage_DispatchMethod(
+ _cb, mi, cc, cr, cop, meth, in, out);
+}
+
+CMMethodMIStub(
+ LMI_DiskPhysicalPackage,
+ LMI_DiskPhysicalPackage,
+ _cb,
+ LMI_DiskPhysicalPackageInitialize())
+
+KUint32 LMI_DiskPhysicalPackage_IsCompatible(
+ const CMPIBroker* cb,
+ CMPIMethodMI* mi,
+ const CMPIContext* context,
+ const LMI_DiskPhysicalPackageRef* self,
+ const KRef* ElementToCheck,
+ CMPIStatus* status)
+{
+ KUint32 result = KUINT32_INIT;
+
+ KSetStatus(status, ERR_NOT_SUPPORTED);
+ return result;
+}
+
+KONKRET_REGISTRATION(
+ "root/cimv2",
+ "LMI_DiskPhysicalPackage",
+ "LMI_DiskPhysicalPackage",
+ "instance method")
diff --git a/src/hardware/LMI_Hardware.h b/src/hardware/LMI_Hardware.h
index 0ea6237..6ca6ab2 100644
--- a/src/hardware/LMI_Hardware.h
+++ b/src/hardware/LMI_Hardware.h
@@ -46,5 +46,6 @@ const char *provider_name;
#define BATTERY_PHYS_PKG_CLASS_NAME "BatteryPhysicalPackage"
#define PCI_DEVICE_CLASS_NAME "PCIDevice"
#define PCI_BRIDGE_CLASS_NAME "PCIBridge"
+#define DISK_PHYS_PKG_CLASS_NAME "DiskPhysicalPackage"
#endif /* LMI_HARDWARE_H_ */
diff --git a/src/hardware/dmidecode.h b/src/hardware/dmidecode.h
index d139f38..e293cde 100644
--- a/src/hardware/dmidecode.h
+++ b/src/hardware/dmidecode.h
@@ -160,7 +160,7 @@ typedef struct _DmiBattery {
/*
* Get array of processors according to the dmidecode program.
- * @param cpu array of cpus, this function will allocate necessary memory,
+ * @param cpus array of cpus, this function will allocate necessary memory,
* but caller is responsible for freeing it
* @param cpus_nb number of processors in cpus
* @return 0 if success, negative value otherwise
diff --git a/src/hardware/smartctl.c b/src/hardware/smartctl.c
new file mode 100644
index 0000000..750dea6
--- /dev/null
+++ b/src/hardware/smartctl.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2013 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 "smartctl.h"
+
+/*
+ * Initialize SmartctlHdd attributes.
+ * @param hdd
+ */
+void init_smctlhdd_struct(SmartctlHdd *hdd)
+{
+ hdd->dev_path = NULL;
+ hdd->dev_basename = NULL;
+ hdd->manufacturer = NULL;
+ hdd->model = NULL;
+ hdd->serial_number = NULL;
+ hdd->name = NULL;
+}
+
+/*
+ * Check attributes of hdd structure and fill in defaults if needed.
+ * @param hdd
+ * @return 0 if success, negative value otherwise
+ */
+short check_smctlhdd_attributes(SmartctlHdd *hdd)
+{
+ short ret = -1;
+
+ if (!hdd->dev_path) {
+ if (!(hdd->dev_path = strdup(""))) {
+ goto done;
+ }
+ }
+ if (!hdd->dev_basename) {
+ if (!(hdd->dev_basename = strdup(""))) {
+ goto done;
+ }
+ }
+ if (!hdd->manufacturer) {
+ if (!(hdd->manufacturer = strdup(""))) {
+ goto done;
+ }
+ }
+ if (!hdd->model) {
+ if (!(hdd->model = strdup(""))) {
+ goto done;
+ }
+ }
+ if (!hdd->serial_number) {
+ if (!(hdd->serial_number = strdup(""))) {
+ goto done;
+ }
+ }
+ if (!hdd->name) {
+ if (!(hdd->name = strdup(""))) {
+ goto done;
+ }
+ }
+
+ ret = 0;
+
+done:
+ if (ret != 0) {
+ warn("Failed to allocate memory.");
+ }
+
+ return ret;
+}
+
+short scan_smctlhdd_devices(SmartctlHdd **hdds, unsigned *hdds_nb)
+{
+ short ret = -1;
+ unsigned i, curr_hdd = 0, buffer_size = 0, sec_buffer_size = 0;
+ char **buffer = NULL, **sec_buffer = NULL;
+ struct stat sb;
+
+ smartctl_free_hdds(hdds, hdds_nb);
+
+ /* get smartctl output */
+ if (run_command("smartctl --scan", &buffer, &buffer_size) != 0) {
+ goto done;
+ }
+
+ /* count hard drives - one line of output is one device */
+ *hdds_nb = buffer_size;
+
+ /* if no hard drive was found */
+ if (*hdds_nb < 1) {
+ warn("Smartctl didn't recognize any hard drive.");
+ goto done;
+ }
+
+ /* allocate memory for hard drives */
+ *hdds = (SmartctlHdd *)calloc(*hdds_nb, sizeof(SmartctlHdd));
+ if (!(*hdds)) {
+ warn("Failed to allocate memory.");
+ *hdds_nb = 0;
+ goto done;
+ }
+
+ /* parse hard drive's dev path */
+ for (i = 0; i < buffer_size; i++) {
+ init_smctlhdd_struct(&(*hdds)[i]);
+
+ if (explode(buffer[i], NULL, &sec_buffer, &sec_buffer_size) != 0 ||
+ sec_buffer_size < 1) {
+ free_2d_buffer(&sec_buffer, &sec_buffer_size);
+ continue;
+ }
+
+ if (stat(sec_buffer[0], &sb) != 0) {
+ warn("Stat() call on file \"%s\" failed: %s",
+ sec_buffer[0], strerror(errno));
+ free_2d_buffer(&sec_buffer, &sec_buffer_size);
+ continue;
+ }
+
+ if ((sb.st_mode & S_IFMT) != S_IFBLK) {
+ warn("File \"%s\" is not a block device.", sec_buffer[0]);
+ free_2d_buffer(&sec_buffer, &sec_buffer_size);
+ continue;
+ }
+
+ (*hdds)[curr_hdd].dev_path = strdup(sec_buffer[0]);
+ (*hdds)[curr_hdd].dev_basename = strdup(basename(sec_buffer[0]));
+ if (!(*hdds)[curr_hdd].dev_path || !(*hdds)[curr_hdd].dev_basename) {
+ warn("Failed to allocate memory.");
+ free_2d_buffer(&sec_buffer, &sec_buffer_size);
+ continue;
+ }
+
+ curr_hdd++;
+ free_2d_buffer(&sec_buffer, &sec_buffer_size);
+ }
+
+ if (curr_hdd != *hdds_nb) {
+ warn("There's some \"smartctl --scan\" output mismatch, "
+ "not all reported drives were processed.");
+ SmartctlHdd *tmp_hdd = (SmartctlHdd *)realloc(*hdds,
+ curr_hdd * sizeof(SmartctlHdd));
+ if (!tmp_hdd) {
+ warn("Failed to allocate memory.");
+ goto done;
+ }
+ *hdds = tmp_hdd;
+ *hdds_nb = curr_hdd;
+ }
+
+ ret = 0;
+
+done:
+ free_2d_buffer(&buffer, &buffer_size);
+
+ if (ret != 0) {
+ smartctl_free_hdds(hdds, hdds_nb);
+ }
+
+ return ret;
+}
+
+short smartctl_get_hdds(SmartctlHdd **hdds, unsigned *hdds_nb)
+{
+ short ret = -1;
+ unsigned i, curr_hdd, buffer_size = 0;
+ char **buffer = NULL, *buf;
+
+ if (scan_smctlhdd_devices(hdds, hdds_nb) != 0) {
+ goto done;
+ }
+
+ for (curr_hdd = 0; curr_hdd < *hdds_nb; curr_hdd++) {
+ /* get smartctl output */
+ char command[PATH_MAX];
+ snprintf(command, PATH_MAX, "smartctl -i %s",
+ (*hdds)[curr_hdd].dev_path);
+ if (run_command(command, &buffer, &buffer_size) != 0) {
+ continue;
+ }
+
+ /* parse information about hard drives */
+ for (i = 0; i < buffer_size; i++) {
+ /* Model */
+ buf = copy_string_part_after_delim(buffer[i], "Device Model:");
+ if (buf) {
+ (*hdds)[curr_hdd].model = buf;
+ buf = NULL;
+ continue;
+ }
+ /* Serial Number */
+ buf = copy_string_part_after_delim(buffer[i], "Serial Number:");
+ if (buf) {
+ (*hdds)[curr_hdd].serial_number = buf;
+ buf = NULL;
+ continue;
+ }
+ /* Name */
+ buf = copy_string_part_after_delim(buffer[i], "Model Family:");
+ if (buf) {
+ (*hdds)[curr_hdd].name = buf;
+ buf = NULL;
+ continue;
+ }
+ }
+
+ free_2d_buffer(&buffer, &buffer_size);
+
+ /* get vendor from sysfs */
+ char sysfs_path[PATH_MAX];
+ snprintf(sysfs_path, PATH_MAX, SYSFS_BLOCK_PATH "/%s/device/vendor",
+ (*hdds)[curr_hdd].dev_basename);
+ path_get_string(sysfs_path, &(*hdds)[curr_hdd].manufacturer);
+
+ /* fill in default attributes if needed */
+ if (check_smctlhdd_attributes(&(*hdds)[curr_hdd]) != 0) {
+ goto done;
+ }
+ }
+
+ ret = 0;
+
+done:
+ if (ret != 0) {
+ smartctl_free_hdds(hdds, hdds_nb);
+ }
+
+ return ret;
+}
+
+void smartctl_free_hdds(SmartctlHdd **hdds, unsigned *hdds_nb)
+{
+ unsigned i;
+
+ if (*hdds && *hdds_nb > 0) {
+ for (i = 0; i < *hdds_nb; i++) {
+ free((*hdds)[i].dev_path);
+ (*hdds)[i].dev_path = NULL;
+ free((*hdds)[i].dev_basename);
+ (*hdds)[i].dev_basename = NULL;
+ free((*hdds)[i].manufacturer);
+ (*hdds)[i].manufacturer = NULL;
+ free((*hdds)[i].model);
+ (*hdds)[i].model = NULL;
+ free((*hdds)[i].serial_number);
+ (*hdds)[i].serial_number = NULL;
+ free((*hdds)[i].name);
+ (*hdds)[i].name = NULL;
+ }
+ free(*hdds);
+ }
+
+ *hdds_nb = 0;
+ *hdds = NULL;
+}
diff --git a/src/hardware/smartctl.h b/src/hardware/smartctl.h
new file mode 100644
index 0000000..5880e3a
--- /dev/null
+++ b/src/hardware/smartctl.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 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>
+ */
+
+#ifndef SMARTCTL_H_
+#define SMARTCTL_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include "utils.h"
+#include "sysfs.h"
+
+/* 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 */
+} SmartctlHdd;
+
+/*
+ * Get array of hard drives according to the smartclt program.
+ * @param hdds array of hdds, this function will allocate necessary memory,
+ * but caller is responsible for freeing it
+ * @param hdds_nb number of hard drives in hdds
+ * @return 0 if success, negative value otherwise
+ */
+short smartctl_get_hdds(SmartctlHdd **hdds, unsigned *hdds_nb);
+
+/*
+ * Free array of hard drive structures.
+ * @param hdds array of hdds
+ * @param hdds_nb number of hdds
+ */
+void smartctl_free_hdds(SmartctlHdd **hdds, unsigned *hdds_nb);
+
+#endif /* SMARTCTL_H_ */
diff --git a/src/hardware/sysfs.c b/src/hardware/sysfs.c
index 4410ff7..aab2ba6 100644
--- a/src/hardware/sysfs.c
+++ b/src/hardware/sysfs.c
@@ -21,12 +21,6 @@
#include "sysfs.h"
-/*
- * Read unsigned value from file.
- * @param path of file
- * @paratm result
- * @return 0 if success, negative value otherwise
- */
short path_get_unsigned(const char *path, unsigned *result)
{
short ret = -1;
@@ -54,12 +48,6 @@ done:
return ret;
}
-/*
- * Read string value from file.
- * @param path of file
- * @paratm result
- * @return 0 if success, negative value otherwise
- */
short path_get_string(const char *path, char **result)
{
short ret = -1;
diff --git a/src/hardware/sysfs.h b/src/hardware/sysfs.h
index 6ff7085..5fbe6a1 100644
--- a/src/hardware/sysfs.h
+++ b/src/hardware/sysfs.h
@@ -36,6 +36,7 @@
#define SYSFS_PATH "/sys/devices/system"
#define SYSFS_CPU_PATH SYSFS_PATH "/cpu"
#define SYSFS_KERNEL_MM "/sys/kernel/mm"
+#define SYSFS_BLOCK_PATH "/sys/class/block"
/* Transparent memory huge pages statuses. */
@@ -58,6 +59,21 @@ typedef struct _SysfsCpuCache {
unsigned line_size; /* Cache Line Size */
} SysfsCpuCache;
+/*
+ * Read unsigned value from file.
+ * @param path of file
+ * @paratm result
+ * @return 0 if success, negative value otherwise
+ */
+short path_get_unsigned(const char *path, unsigned *result);
+
+/*
+ * Read string value from file.
+ * @param path of file
+ * @paratm result
+ * @return 0 if success, negative value otherwise
+ */
+short path_get_string(const char *path, char **result);
/*
* Get array of processor caches from sysfs.