Added HDD monitring via SMART on Linux
authorVictor Kirhenshtein <victor@netxms.org>
Thu, 24 Feb 2005 17:38:49 +0000 (17:38 +0000)
committerVictor Kirhenshtein <victor@netxms.org>
Thu, 24 Feb 2005 17:38:49 +0000 (17:38 +0000)
.gitattributes
include/ata.h
src/agent/subagents/linux/Makefile.am
src/agent/subagents/linux/hddinfo.cpp [new file with mode: 0644]
src/agent/subagents/linux/linux.cpp

index 84265ec..899ea83 100644 (file)
@@ -176,6 +176,7 @@ src/agent/subagents/freebsd/system.h -text
 src/agent/subagents/linux/Makefile.am -text
 src/agent/subagents/linux/disk.cpp -text
 src/agent/subagents/linux/disk.h -text
+src/agent/subagents/linux/hddinfo.cpp -text
 src/agent/subagents/linux/linux.cpp -text
 src/agent/subagents/linux/net.cpp -text
 src/agent/subagents/linux/net.h -text
index cfca62c..f4f653d 100644 (file)
@@ -153,4 +153,18 @@ typedef struct ata_smart_values
 } ATA_SMART_VALUES; 
 #pragma pack()
 
+
+//
+// Default values for SMART registers
+//
+
+#ifndef SMART_CYL_LOW
+#define SMART_CYL_LOW   0xC2
+#endif
+
+#ifndef SMART_CYL_HI
+#define SMART_CYL_HI    0x4F
+#endif
+
+
 #endif
index 3f258d9..4102920 100644 (file)
@@ -1,6 +1,6 @@
 INCLUDES=-I@top_srcdir@/include
 
 lib_LTLIBRARIES = libnsm_linux.la
-libnsm_linux_la_SOURCES = linux.cpp proc.cpp system.cpp disk.cpp net.cpp
+libnsm_linux_la_SOURCES = linux.cpp proc.cpp system.cpp disk.cpp net.cpp hddinfo.cpp
 
 EXTRA_DIST = disk.h net.h proc.h system.h
diff --git a/src/agent/subagents/linux/hddinfo.cpp b/src/agent/subagents/linux/hddinfo.cpp
new file mode 100644 (file)
index 0000000..b758c29
--- /dev/null
@@ -0,0 +1,176 @@
+/* 
+** NetXMS Linux subagent
+** Copyright (C) 2005 Victor Kirhenshtein
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program 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 General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+** $module: hddinfo.cpp
+**
+**/
+
+#include <nms_common.h>
+#include <nms_agent.h>
+#include <ata.h>
+#include <sys/ioctl.h>
+
+
+//
+// Constants
+//
+
+#define HDIO_DRIVE_CMD            0x031f
+#define HDIO_DRIVE_TASK           0x031e
+#define HDIO_DRIVE_TASKFILE       0x031d
+#define HDIO_GET_IDENTITY         0x030d
+
+#define HDIO_DRIVE_CMD_OFFSET     4
+
+#define ATTR_TYPE_BYTE        0
+#define ATTR_TYPE_HEX_STRING  1
+
+
+//
+// Get value of specific attribute from SMART_ATA_VALUES structure
+//
+
+static BOOL GetAttributeValue(ATA_SMART_VALUES *pSmartValues, BYTE bAttr,
+                              char *pValue, int nType)
+{
+   int i;
+   BOOL bResult = FALSE;
+
+   for(i = 0; i < NUMBER_ATA_SMART_ATTRIBUTES; i++)
+      if (pSmartValues->vendor_attributes[i].id == bAttr)
+      {
+         switch(nType)
+         {
+            case ATTR_TYPE_BYTE:
+               ret_uint(pValue, pSmartValues->vendor_attributes[i].raw[0]);
+               break;
+            case ATTR_TYPE_HEX_STRING:
+               BinToStr(pSmartValues->vendor_attributes[i].raw, 6, pValue);
+               break;
+         }
+         bResult = TRUE;
+         break;
+      }
+   return bResult;
+}
+
+
+//
+// Handler for PhysicalDisk.*
+//
+
+LONG H_PhysicalDiskInfo(char *pszParam, char *pszArg, char *pValue)
+{
+   LONG nRet = SYSINFO_RC_ERROR, nDisk, nCmd;
+   char szBuffer[MAX_PATH];
+   int hDevice;
+   BYTE ioBuff[1024];
+
+   if (!NxGetParameterArg(pszParam, 1, szBuffer, MAX_PATH))
+      return SYSINFO_RC_UNSUPPORTED;
+
+   // Open device
+   hDevice = open(szBuffer, O_RDWR);
+   if (hDevice != -1)
+   {
+      // Setup request's common fields
+      memset(ioBuff, 0, sizeof(ioBuff));
+      ioBuff[0] = ATA_SMART_CMD;
+
+      // Setup request-dependent fields
+      switch(pszArg[0])
+      {
+         case 'A':   // Generic SMART attribute
+         case 'T':   // Temperature
+            ioBuff[1] = 1;
+            ioBuff[2] = ATA_SMART_READ_VALUES;
+            ioBuff[3] = 1;
+            nCmd = HDIO_DRIVE_CMD;
+            break;
+         case 'S':   // Disk status reported by SMART
+            ioBuff[1] = ATA_SMART_STATUS;
+                ioBuff[4] = SMART_CYL_HI;
+            ioBuff[5] = SMART_CYL_LOW;
+            nCmd = HDIO_DRIVE_TASK;
+            break;
+         default:
+            nRet = SYSINFO_RC_UNSUPPORTED;
+            break;
+      }
+
+
+      if (ioctl(hDevice, nCmd, ioBuff) >= 0)
+      {
+         switch(pszArg[0])
+         {
+            case 'A':   // Generic attribute
+               if (NxGetParameterArg(pszParam, 2, szBuffer, 128))
+               {
+                  LONG nAttr;
+                  char *eptr;
+
+                  nAttr = strtol(szBuffer, &eptr, 0);
+                  if ((*eptr != 0) || (nAttr <= 0) || (nAttr > 255))
+                  {
+                     nRet = SYSINFO_RC_UNSUPPORTED;
+                  }
+                  else
+                  {
+                     if (GetAttributeValue((ATA_SMART_VALUES *)&ioBuff[HDIO_DRIVE_CMD_OFFSET],
+                                           (BYTE)nAttr, pValue, ATTR_TYPE_HEX_STRING))
+                        nRet = SYSINFO_RC_SUCCESS;
+                  }
+               }
+               else
+               {
+                  nRet = SYSINFO_RC_UNSUPPORTED;
+               }
+               break;
+            case 'T':   // Temperature
+               if (GetAttributeValue((ATA_SMART_VALUES *)&ioBuff[HDIO_DRIVE_CMD_OFFSET],
+                                     0xC2, pValue, ATTR_TYPE_BYTE))
+               {
+                  nRet = SYSINFO_RC_SUCCESS;
+               }
+               break;
+            case 'S':   // SMART status
+               if ((ioBuff[4] == SMART_CYL_HI) && (ioBuff[5] == SMART_CYL_LOW))
+               {
+                  ret_int(pValue, 0);  // Status is OK
+               }
+               else if ((ioBuff[4] == 0x2C) && (ioBuff[5] == 0xF4))
+               {
+                  ret_int(pValue, 1);  // Status is BAD
+               }
+               else
+               {
+                  ret_int(pValue, 2);  // Status is UNKNOWN
+               }
+               nRet = SYSINFO_RC_SUCCESS;
+               break;
+            default:
+               nRet = SYSINFO_RC_UNSUPPORTED;
+               break;
+         }
+      }
+
+      close(hDevice);
+   }
+
+   return nRet;
+}
index 434fe93..418219d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: linux.cpp,v 1.14 2005-02-21 20:16:05 victor Exp $ */
+/* $Id: linux.cpp,v 1.15 2005-02-24 17:38:49 victor Exp $ */
 
 /* 
 ** NetXMS subagent for GNU/Linux
 #include "system.h"
 #include "disk.h"
 
+
+//
+// Externals
+//
+
+LONG H_PhysicalDiskInfo(char *pszParam, char *pszArg, char *pValue);
+
+
 //
 // Subagent information
 //
@@ -47,6 +55,13 @@ static NETXMS_SUBAGENT_PARAM m_parameters[] =
    { "Net.IP6.Forwarding",           H_NetIpForwarding, (char *)6,
                        DCI_DT_INT,             "IPv6 forwarding status" },
 
+   { "PhysicalDisk.SmartAttr(*)",    H_PhysicalDiskInfo, "A",
+                       DCI_DT_STRING,  "" },
+   { "PhysicalDisk.SmartStatus(*)",  H_PhysicalDiskInfo, "S",
+                       DCI_DT_INT,             "Status of hard disk {instance} reported by SMART" },
+   { "PhysicalDisk.Temperature(*)",  H_PhysicalDiskInfo, "T",
+                       DCI_DT_INT,             "Temperature of hard disk {instance}" },
+
    { "Process.Count(*)",             H_ProcessCount,    (char *)0,
                        DCI_DT_UINT,    "Number of {instance} processes" },
    { "System.ProcessCount",          H_ProcessCount,    (char *)1,
@@ -127,6 +142,9 @@ extern "C" BOOL NxSubAgentInit(NETXMS_SUBAGENT_INFO **ppInfo)
 /*
 
 $Log: not supported by cvs2svn $
+Revision 1.14  2005/02/21 20:16:05  victor
+Fixes in parameter data types and descriptions
+
 Revision 1.13  2005/01/24 19:46:50  alk
 SourcePackageSupport; return type/comment addded