From: jacob Date: Thu, 14 Jul 2005 21:00:40 +0000 (+0000) Subject: Initial import of lustre-snmp module. X-Git-Tag: v1_7_100~1^41 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=c6bc5eb7d073d5a7b7d0934d92bfd8eab15fc825 Initial import of lustre-snmp module. --- c6bc5eb7d073d5a7b7d0934d92bfd8eab15fc825 diff --git a/snmp/Lustre-MIB.txt b/snmp/Lustre-MIB.txt new file mode 100644 index 0000000..db662d1 --- /dev/null +++ b/snmp/Lustre-MIB.txt @@ -0,0 +1,966 @@ +-- +-- Lustre Filesystem MIB Module +-- + +LUSTRE-MIB DEFINITIONS ::= BEGIN + IMPORTS + MODULE-IDENTITY, OBJECT-TYPE, enterprises, Integer32, + Unsigned32, Counter64 + FROM SNMPv2-SMI + DisplayString, TruthValue, RowStatus + FROM SNMPv2-TC; + +lustreMIB MODULE-IDENTITY + LAST-UPDATED "200505150100Z" + ORGANIZATION "Cluster Filesystems, Inc." + CONTACT-INFO + " info@clusterfs.com + + Postal: Cluster File Systems, Inc. + 110 Capen St + Medford, MA 02155 + USA" + + DESCRIPTION + "Management information for the Lustre parallel filesystem." + + ::= { clusterFileSystemsSNMP 1 } + +--============================================================================ +-- +-- Administrative assignments +-- +--============================================================================ + +clusterFileSystems OBJECT IDENTIFIER ::= { enterprises 13140 } +clusterFileSystemsSNMP OBJECT IDENTIFIER ::= { clusterFileSystems 2 } + +lustreMgmtTraps OBJECT IDENTIFIER ::= { lustreMIB 0 } +systemInformation OBJECT IDENTIFIER ::= { lustreMIB 1 } +objectStorageTargets OBJECT IDENTIFIER ::= { lustreMIB 2 } +objectStorageClients OBJECT IDENTIFIER ::= { lustreMIB 3 } +metaDataServers OBJECT IDENTIFIER ::= { lustreMIB 4 } +metaDataClients OBJECT IDENTIFIER ::= { lustreMIB 5 } +lustreClients OBJECT IDENTIFIER ::= { lustreMIB 6 } +logicalObjectVolume OBJECT IDENTIFIER ::= { lustreMIB 7 } +lustreLDLM OBJECT IDENTIFIER ::= { lustreMIB 8 } + + +--============================================================================ +-- +-- System Information +-- +--============================================================================ + +sysVersion OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The Lustre version string." + ::= { systemInformation 1 } + +sysKernelVersion OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The Lustre kernel version string." + ::= { systemInformation 2 } + +sysHealthCheck OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The Lustre kernel health check string. Contains 'healthy' or + 'NOT healthy' plus descriptive information on the failure" + ::= { systemInformation 3 } + +sysStatus OBJECT-TYPE + SYNTAX INTEGER { + -- The following two values are states: + -- they may be read, or written + online(1), + offline(2), + -- The following two values are states: + -- they may be read, but not written + onlinePending(3), + offlinePending(4), + -- The following value is an action: + -- this value may be written, but never read. + restart(5) + } + MAX-ACCESS read-write + STATUS current + DESCRIPTION + "The sysStatus variable is used to manage the overall state of the + Lustre components on a system. It has five defined values: + + - 'online', which indicates that all of the configured + Lustre components have been successfully activated; + + - 'offline', which indicates that all of the Lustre + components have been successfully deactivated; + + - 'onlinePending', which indicates one or more failures + occurred in transitioning to the 'online' state; + + - 'offlinePending', which indicates one or more failures + occurred in transitioning to the 'offline' state; + + - 'restart', which is supplied by a management station + wishing to transition first to the 'offline' state, and + then to the 'online' state. + + Only three of these five values may be specified in a + management protocol set operation: 'online', 'offline', + 'restart'. Only four of the five values will be returned in + response to a management protocol retrieval operation: + 'online', 'offline', 'onlinePending', 'offlinePending'." + + ::= { systemInformation 4 } + +--============================================================================ +-- +-- Object Storage Targets +-- +--============================================================================ + +osdNumber OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of Object Storage Devices on a OST system." + ::= { objectStorageTargets 1 } + +osdTable OBJECT-TYPE + SYNTAX SEQUENCE OF OsdEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table listing the Object Storage Devices available on a OST system. + The number of entries in this table is available in osdNumber." + ::= { objectStorageTargets 2 } + +osdEntry OBJECT-TYPE + SYNTAX OsdEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table entry with information an Object Storage Device on a OST + system." + INDEX { osdIndex } + ::= { osdTable 1 } + +OsdEntry ::= + SEQUENCE { + osdIndex Unsigned32, + osdUUID DisplayString, + osdCommonName DisplayString, + osdCapacity Counter64, + osdFreeCapacity Counter64, + osdObjects Counter64, + osdFreeObjects Counter64 + } + +osdIndex OBJECT-TYPE + SYNTAX Unsigned32 (1..2147483647) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Index into the table of Object Storage Devices on a OST system." + ::= { osdEntry 1 } + +osdUUID OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The Lustre Universally Unique Identifier (UUID) for the Object + Storage Device." + ::= { osdEntry 2 } + +osdCommonName OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Its the instance name given by Lustre proc subsystem for + each of the object storage device." + ::= { osdEntry 3 } + +osdCapacity OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The capacity of the Object Storage Device in bytes." + ::= { osdEntry 4 } + +osdFreeCapacity OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The remaining free capacity of the Object Storage Device in bytes." + ::= { osdEntry 5 } + +osdObjects OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The maximum number of objects that may be stored in an Object + Storage Device." + ::= { osdEntry 6 } + +osdFreeObjects OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of unused objects on an Object Storage Device." + ::= { osdEntry 7 } + +--============================================================================ +-- +-- Object Storage Client +-- +--============================================================================ + +oscNumber OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of Object Storage Clients." + ::= { objectStorageClients 1 } + +oscTable OBJECT-TYPE + SYNTAX SEQUENCE OF OscEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table listing the Object Storage Clients available. + The number of entries in this table is available in oscNumber." + ::= { objectStorageClients 2 } + +oscEntry OBJECT-TYPE + SYNTAX OscEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table entry with information an Object Storage Clients." + INDEX { oscIndex } + ::= { oscTable 1 } + +OscEntry ::= + SEQUENCE { + oscIndex Unsigned32, + oscUUID DisplayString, + oscCommonName DisplayString, + oscOSTServerUUID DisplayString, + oscCapacity Counter64, + oscFreeCapacity Counter64, + oscObjects Counter64, + oscFreeObjects Counter64 + } + +oscIndex OBJECT-TYPE + SYNTAX Unsigned32 (1..2147483647) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Index into the table of Object Storage Clients." + ::= { oscEntry 1 } + +oscUUID OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The Lustre Universally Unique Identifier (UUID) for the Object + Storage Device." + ::= { oscEntry 2 } + +oscCommonName OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Its the instance name given by Lustre proc subsystem for + each of the object storage device." + ::= { oscEntry 3 } + +oscOSTServerUUID OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The Lustre Object Storage Target UUID accessed by Object Storage Client. + This string also contains a state name, and possibly a DEACTIVATED flag." + ::= { oscEntry 4 } + +oscCapacity OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The capacity of the Object Storage Client in bytes." + ::= { oscEntry 5 } + +oscFreeCapacity OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The remaining free capacity of the Object Storage Client in bytes." + ::= { oscEntry 6 } + +oscObjects OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The maximum number of objects that may be stored in an Object + Storage Client." + ::= { oscEntry 7 } + +oscFreeObjects OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of unused objects on an Object Storage Client." + ::= { oscEntry 8 } + +--============================================================================ +-- +-- Metadata Servers +-- +--============================================================================ + +mddNumber OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of Metadata Devices on a MDS system." + ::= { metaDataServers 1 } + +mddTable OBJECT-TYPE + SYNTAX SEQUENCE OF MddEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table listing the Meta Data Devices available on a MDS system. + The number of entries in this table is available in mddNumber." + ::= { metaDataServers 2 } + +mddEntry OBJECT-TYPE + SYNTAX MddEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table entry with information an Meta Data Device on a MDS system." + INDEX { mddIndex } + ::= { mddTable 1 } + +MddEntry ::= + SEQUENCE { + mddIndex Unsigned32, + mddUUID DisplayString, + mddCommonName DisplayString, + mddCapacity Counter64, + mddFreeCapacity Counter64, + mddFiles Counter64, + mddFreeFiles Counter64 + } + +mddIndex OBJECT-TYPE + SYNTAX Unsigned32 (1..2147483647) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Index into the table of Meta Data Devices on a MDS system." + ::= { mddEntry 1 } + +mddUUID OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The Lustre Universal Unique Identifier (UUID) for the Meta Data + Device." + ::= { mddEntry 2 } + +mddCommonName OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The common name of the Meta Data Device. + Its the instance name given by Lustre proc subsystem for + each of the Meta Data Device." + ::= { mddEntry 3 } + +mddCapacity OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The capacity of the Meta Data Device in bytes." + ::= { mddEntry 4 } + +mddFreeCapacity OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The remaining free capacity of the Meta Data Device in bytes." + ::= { mddEntry 5 } + +mddFiles OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The maximum number of files that may be stored on a Meta Data + Device." + ::= { mddEntry 6 } + +mddFreeFiles OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of unused files on a Meta Data Device." + ::= { mddEntry 7 } + + +--============================================================================ +-- +-- Metadata Clients +-- +--============================================================================ + +mdcNumber OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of Metadata Clients." + ::= { metaDataClients 1 } + +mdcTable OBJECT-TYPE + SYNTAX SEQUENCE OF MdcEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table listing the Meta Data Clients. + The number of entries in this table is available in mdcNumber." + ::= { metaDataClients 2 } + +mdcEntry OBJECT-TYPE + SYNTAX MdcEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table entry with information an Meta Data Client." + INDEX { mdcIndex } + ::= { mdcTable 1 } + +MdcEntry ::= + SEQUENCE { + mdcIndex Unsigned32, + mdcUUID DisplayString, + mdcCommonName DisplayString, + mdcMDSServerUUID DisplayString, + mdcCapacity Counter64, + mdcFreeCapacity Counter64, + mdcFiles Counter64, + mdcFreeFiles Counter64 + } + +mdcIndex OBJECT-TYPE + SYNTAX Unsigned32 (1..2147483647) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Index into the table of Meta Data Client." + ::= { mdcEntry 1 } + +mdcUUID OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The Lustre Universal Unique Identifier (UUID) for the Meta Data Client." + ::= { mdcEntry 2 } + +mdcCommonName OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The common name of the Meta Data Client. + Its the instance name given by Lustre proc subsystem for + each of the Meta Data Client." + ::= { mdcEntry 3 } + +mdcMDSServerUUID OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The Lustre Meta data server UUID accessed by Metadata Client. + This string also contains a state name, and possibly a DEACTIVATED flag." + ::= { mdcEntry 4 } + +mdcCapacity OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The capacity of the Meta Data Client in bytes." + ::= { mdcEntry 5 } + +mdcFreeCapacity OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The remaining free capacity of the Meta Data Client in bytes." + ::= { mdcEntry 6 } + +mdcFiles OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The maximum number of files that may be stored on a Meta Data Client." + ::= { mdcEntry 7 } + +mdcFreeFiles OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of unused files on a Meta Data Client." + ::= { mdcEntry 8 } + +--============================================================================ +-- +-- Lustre Clients +-- +--============================================================================ + +cliMountNumber OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of Lustre mounts that are currently on a client system." + ::= { lustreClients 1 } + +cliMountTable OBJECT-TYPE + SYNTAX SEQUENCE OF CliMountEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table listing the Lustre file system mount points and their + configurations. The current number of entries is specified by + cliMountNumber." + ::= { lustreClients 2 } + +cliMountEntry OBJECT-TYPE + SYNTAX CliMountEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Information about a single Lustre file system mount point." + INDEX { cliIndex } + ::= { cliMountTable 1 } + +CliMountEntry ::= + SEQUENCE { + cliIndex Unsigned32, + cliUUID DisplayString, + cliCommonName DisplayString, + cliMDSUUID DisplayString, + cliMDSCommonName DisplayString, + cliUsesLOV TruthValue, + cliLOVUUID DisplayString, + cliLOVCommonName DisplayString + } + +cliIndex OBJECT-TYPE + SYNTAX Unsigned32 (1..2147483647) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Index into the table of Lustre file system mount points on a + client system." + ::= { cliMountEntry 1 } + +cliUUID OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The Lustre Universal Unique Identifier (UUID) for a Lustre + file system mount point." + ::= { cliMountEntry 2 } + +cliCommonName OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Its the instance name given by Lustre proc subsystem for + each of the Lustre client mount point." + ::= { cliMountEntry 3 } + +cliMDCUUID OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The UUID of the Metadata Client to which a Lustre file system + mount point is connected." + ::= { cliMountEntry 4 } + +cliMDCCommonName OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "This is the name of the Metadata Client to which a Lustre client + file system mount point is connected." + ::= { cliMountEntry 5 } + +cliUsesLOV OBJECT-TYPE + SYNTAX TruthValue + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "This variable is true(1) if a Lustre file system mount point + is using a Logical Object volume (LOV), and false(2) otherwise." + ::= { cliMountEntry 6 } + +cliLOVUUID OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The UUID of the LOV to which a Lustre file system + mount point is connected." + ::= { cliMountEntry 7 } + +cliLOVCommonName OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "This is the name of the LOV to which a Lustre client + file system mount point is connected." + ::= { cliMountEntry 8 } + + +--============================================================================ +-- +-- Logical Object Volume +-- +--============================================================================ + +lovNumber OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of LOV instances." + ::= { logicalObjectVolume 1 } + +lovTable OBJECT-TYPE + SYNTAX SEQUENCE OF LovEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table listing the statistics for LOV instances available on + a Lustre configured node." + ::= { logicalObjectVolume 2 } + +lovEntry OBJECT-TYPE + SYNTAX LovEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table entry with information on LOV stats for all LOV instances + available on a Lustre configured node." + INDEX { lovIndex } + ::= { lovTable 1 } + +LovEntry ::= + SEQUENCE { + lovIndex Unsigned32, + lovUUID DisplayString, + lovCommonName DisplayString, + lovNumOBD Unsigned32, + lovNumActiveOBD Unsigned32, + lovCapacity Counter64, + lovFreeCapacity Counter64, + lovFiles Counter64, + lovFreeFiles Counter64, + lovStripeCount Unsigned32, + lovStripeOffset Unsigned32, + lovStripeSize Unsigned32, + lovStripeType Unsigned32 + } + +lovIndex OBJECT-TYPE + SYNTAX Unsigned32 (1..2147483647) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Index into the table of LOV stats for LOV instances available + on a Lustre configured system." + ::= { lovEntry 1 } + +lovUUID OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The Lustre Universally Unique Identifier (UUID) for the LOV." + ::= { lovEntry 2 } + +lovCommonName OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Its the instance name given by Lustre proc subsystem for + each of the LOVs." + ::= { lovEntry 3 } + +lovNumOBD OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of OBDs." + ::= { lovEntry 4 } + + +lovNumActiveOBD OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The name of the target OBDs." + ::= { lovEntry 5 } + + +lovCapacity OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The capacity of the LOV in bytes." + ::= { lovEntry 6 } + +lovFreeCapacity OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The remaining free capacity of the LOV in bytes." + ::= { lovEntry 7 } + +lovFiles OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The maximum number of files that may be stored on a LOV." + ::= { lovEntry 8 } + +lovFreeFiles OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of unused files on a LOV." + ::= { lovEntry 9 } + +lovStripeCount OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of stripes on a LOV." + ::= { lovEntry 10 } + +lovStripeOffset OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The stripe offset on a LOV." + ::= { lovEntry 11 } + +lovStripeSize OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The stripe size on a LOV." + ::= { lovEntry 12 } + +lovStripeType OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The stripe type on a LOV." + ::= { lovEntry 13 } + +--============================================================================ +-- +-- Lustre Distributed Lock Manager +-- +--============================================================================ + +ldlmNumber OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The number of LDLM namespaces (Also its the number of instances + in a LDLM table)" + ::= { lustreLDLM 1 } + +ldlmTable OBJECT-TYPE + SYNTAX SEQUENCE OF LdlmEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "A table listing the statistics for LDLM namespaces available on + a Lustre configured node." + ::= { lustreLDLM 2 } + +ldlmEntry OBJECT-TYPE + SYNTAX LdlmEntry + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Table entry with information LDLM stats for all LDLM namespaces + available on a Lustre configured node." + INDEX { ldlmIndex } + ::= { ldlmTable 1 } + +LdlmEntry ::= + SEQUENCE { + ldlmIndex Unsigned32, + ldlmNameSpace DisplayString, + ldlmLockCount Unsigned32, + ldlmUnusedLockCount Unsigned32, + ldlmResourceCount Unsigned32 + } + +ldlmIndex OBJECT-TYPE + SYNTAX Unsigned32 (1..2147483647) + MAX-ACCESS not-accessible + STATUS current + DESCRIPTION + "Index into the table of LDLM stats for LDLM namespaces available + on a Lustre configured system." + ::= { ldlmEntry 1 } + +ldlmNameSpace OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The name of the particular LDLM namespace." + ::= { ldlmEntry 2 } + +ldlmLockCount OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Active Lock count of particular LDLM namespace." + ::= { ldlmEntry 3 } + +ldlmUnusedLockCount OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Unused Lock count of particular LDLM namespace." + ::= { ldlmEntry 4 } + +ldlmResourceCount OBJECT-TYPE + SYNTAX Unsigned32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Resource count of particular LDLM namespace." + ::= { ldlmEntry 5 } + +--============================================================================ +-- +-- Lustre Management Traps +-- +--============================================================================ + + +lustrePortalsCatastropeTrap NOTIFICATION-TYPE + OBJECTS { + lustrePortalsCatastropeReasonString + } + STATUS current + DESCRIPTION + "The Lustre service Failure traps sent to management station in + case of Portals Catastrophe." + ::= { lustreMgmtTraps 1 } + +lustrePortalsCatastropeReasonString OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The portals catastrophe description string." + ::= { lustreMgmtTraps 2 } + +lustreOBDUnhealthyTrap NOTIFICATION-TYPE + OBJECTS { + lustreOBDNameString, + lustreOBDUnhealthyReasonString + } + STATUS current + DESCRIPTION + "The Lustre service Failure traps sent to management station in + on OBD health check failure." + ::= { lustreMgmtTraps 3 } + +lustreOBDNameString OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The health status string." + ::= { lustreMgmtTraps 4 } + +lustreOBDUnhealthyReasonString OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "The health status string." + ::= { lustreMgmtTraps 5 } + +END diff --git a/snmp/Makefile.am b/snmp/Makefile.am new file mode 100644 index 0000000..c1ee04f --- /dev/null +++ b/snmp/Makefile.am @@ -0,0 +1,19 @@ +agent_PROGRAMS := lustresnmp.so +mib_DATA := Lustre-MIB.txt + +lustresnmp_so_SOURCES := \ + lustre-snmp.c \ + lustre-snmp.h \ + lustre-snmp-trap.c \ + lustre-snmp-trap.h \ + lustre-snmp-util.c \ + lustre-snmp-util.h + +lustresnmp_so_LDADD := $(NET_SNMP_LIBS) +lustresnmp_so_CFLAGS := $(NET_SNMP_CFLAGS) +lustresnmp_so_LDFLAGS := -fPIC -shared + +SUBDIRS := +DIST_SUBDIRS := autoconf + +EXTRA_DIST := $(mib_DATA) diff --git a/snmp/README.install b/snmp/README.install new file mode 100644 index 0000000..652c4d5 --- /dev/null +++ b/snmp/README.install @@ -0,0 +1,9 @@ +Steps for installation: + +Update /etc/snmp/snmpd.conf appending the following line: + +dlmod lustresnmp /usr/lib/lustre/snmp/lustresnmp.so + +Or the appropriate path to the snmp module. + +Then, restart the snmpd daemon. diff --git a/snmp/autoconf/Makefile.am b/snmp/autoconf/Makefile.am new file mode 100644 index 0000000..2bb7693 --- /dev/null +++ b/snmp/autoconf/Makefile.am @@ -0,0 +1 @@ +EXTRA_DIST := lustre-snmp.m4 diff --git a/snmp/autoconf/lustre-snmp.m4 b/snmp/autoconf/lustre-snmp.m4 new file mode 100644 index 0000000..2ca0f46 --- /dev/null +++ b/snmp/autoconf/lustre-snmp.m4 @@ -0,0 +1,79 @@ +# +# LS_CONFIGURE +# +# configure bits for lustre-snmp +# +AC_DEFUN([LS_CONFIGURE], +[AC_MSG_CHECKING([whether to try to build SNMP support]) +AC_ARG_ENABLE([snmp], + AC_HELP_STRING([--enable-snmp], + [require SNMP support (default=auto)]), + [],[enable_snmp='auto']) +AC_MSG_RESULT([$enable_snmp]) + +if test x$enable_snmp != xno ; then + AC_CHECK_PROG([NET_SNMP_CONFIG], [net-snmp-config], [net-snmp-config], []) + if test "$NET_SNMP_CONFIG" ; then + NET_SNMP_CFLAGS=$($NET_SNMP_CONFIG --base-cflags) + NET_SNMP_LIBS=$($NET_SNMP_CONFIG --agent-libs) + + CPPFLAGS_save="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $NET_SNMP_CFLAGS" + + LIBS_save="$LIBS" + LIBS="$LIBS $NET_SNMP_LIBS" + + AC_CHECK_HEADER([net-snmp/net-snmp-config.h],[ + AC_CHECK_FUNC([register_mib],[SNMP_SUBDIR="snmp"],[ + LIBS="$LIBS -lwrap" + NET_SNMP_LISB="$NET_SNMP_LIBS -lwrap" + # fail autoconf's cache + unset ac_cv_func_register_mib + AC_CHECK_FUNC([register_mib],[SNMP_SUBDIR="snmp"]) + ]) + ]) + + LIBS="$LIBS_save" + CPPFLAGS="$CPPFLAGS_save" + fi + AC_MSG_CHECKING([for SNMP support]) + if test "$SNMP_SUBDIR" ; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no (see config.log for errors)]) + if test x$enable_snmp = xyes ; then + AC_MSG_ERROR([SNMP support was requested, but unavailable]) + fi + fi +fi + +agentdir='${pkglibdir}/snmp' +mibdir='${pkgdatadir}/snmp/mibs' + +AC_SUBST(SNMP_SUBDIR) +AC_SUBST(NET_SNMP_CFLAGS) +AC_SUBST(NET_SNMP_LIBS) +AC_SUBST(agentdir) +AC_SUBST(mibdir) +]) + +# +# LS_CONDITIONALS +# +# AM_CONDITIONALs for lustre-snmp +# +AC_DEFUN([LS_CONDITIONALS], +[ +]) + +# +# LS_CONFIG_FILE +# +# files that should be generated with AC_OUTPUT +# +AC_DEFUN([LS_CONFIG_FILES], +[AC_CONFIG_FILES([ +snmp/Makefile +snmp/autoconf/Makefile +]) +]) diff --git a/snmp/lustre-snmp-trap.c b/snmp/lustre-snmp-trap.c new file mode 100644 index 0000000..7caf5ce --- /dev/null +++ b/snmp/lustre-snmp-trap.c @@ -0,0 +1,532 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (c) 2005 Cluster File Systems, Inc. + * Author: PJ Kirner + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre 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 Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * include important headers + */ + +#include +#include +#include + +/* + * include our .h file + */ + +#include +#include +#include +#include +#include +#include +#include +#include "lustre-snmp-util.h" + +/************************************************************************** + * Constants + *************************************************************************/ + +#define DEFAULT_POLL_INTERVAL_SECONDS 60 +#define POLL_INTERVAL_ENV_VAR "LSNMP_POLL_INTERVAL" +#define SNMP_HEALTH_CHECK_TEST_FILE "LSNMP_HEALTH_CHECK_TEST_FILE" + +/************************************************************************** + * Trap OIDS + *************************************************************************/ + +static oid objid_snmptrap[] = + { 1,3,6,1,6,3,1,1,4,1,0}; +static oid lustre_portals_trap[] = + { 1,3,6,1,4,1,13140,2,1,0,1}; +static oid lustre_portals_trap_string[]= + { 1,3,6,1,4,1,13140,2,1,0,2}; +static oid lustre_unhealthy_trap[] = + { 1,3,6,1,4,1,13140,2,1,0,3}; +static oid lustre_unhealthy_trap_device_name_string[]= + { 1,3,6,1,4,1,13140,2,1,0,4}; +static oid lustre_unhealthy_trap_reason_string[]= + { 1,3,6,1,4,1,13140,2,1,0,5}; + +/************************************************************************** + * Data structures + *************************************************************************/ + +typedef struct obd_unhealthy_entry_struct{ + + /*1-if seen as part of the the is_unhealthy scan, otherwise 0*/ + int seen; + + /*single linked list pointer*/ + struct obd_unhealthy_entry_struct *next; + + /*obdname - variable size*/ + char name[0]; + +}obd_unhealthy_entry; + +/************************************************************************** + * Local functions + *************************************************************************/ + +int get_poll_interval_seconds(); +void health_poll_worker(unsigned int registration_number, void *clientarg); +void send_portals_catastrophe_trap(char *reason_string); +void send_obd_unhealthy_trap(char *obd_name,char *reason_string); +int is_obd_newly_unhealthy(const char* obd_name); +void obd_unhealthy_scan(void); +void health_entry_parser(void); + +/************************************************************************** + * Global variables + *************************************************************************/ + +static int g_sent_portals_catastrophe = 0; +static obd_unhealthy_entry* g_obd_unhealthy_list = NULL; +static int g_poll_interval_seconds; +static unsigned int g_registration_handle; +static char *g_health_check_test_file = 0; + +/***************************************************************************** + * Function: initilize_trap_handler + * + * Description: Initlized the trap poll haalder. + * + * Input: void + * + * Output: Global g_poll_interval_seconds is set. + * + ****************************************************************************/ + +void initilize_trap_handler(void) +{ + g_poll_interval_seconds = get_poll_interval_seconds(); + + g_registration_handle = snmp_alarm_register(g_poll_interval_seconds, 0, health_poll_worker, NULL); + if (g_registration_handle == 0) + report("%s %s: line %d %s", __FILE__, __FUNCTION__, __LINE__, + "snmp_alarm_register failed"); + + DEBUGMSGTL(("lsnmpd","lsnmp alarm registered poll interval = %d seconds\n",g_poll_interval_seconds)); + + g_health_check_test_file = getenv(SNMP_HEALTH_CHECK_TEST_FILE); + if(g_health_check_test_file != 0) + DEBUGMSGTL(("lsnmpd","lsnmp health check test file set to \'%s\'\n",g_health_check_test_file)); +} + +/***************************************************************************** + * Function: terminate_trap_handler + * + * Description: Terminate the trap poll haalder. + * + * Input: void + * + * Output: Global g_poll_interval_seconds is set. + * + ****************************************************************************/ + +void terminate_trap_handler(void) +{ + snmp_alarm_unregister(g_registration_handle); +} + +/***************************************************************************** + * Function: get_poll_interval_seconds + * + * Description: This function used to get the poll period for timer, which + * is used to read throughput values periodically. + * Input: void + * Output: Alarm period, default value(if env var not set) otherwise. + ****************************************************************************/ + +int get_poll_interval_seconds() +{ + char *alarm_period; + int ret_val = DEFAULT_POLL_INTERVAL_SECONDS; + + /* Get Alarm period for reading the Lustre client table. */ + + alarm_period = getenv(POLL_INTERVAL_ENV_VAR); + if (alarm_period != NULL) { + char *ptr = alarm_period; + while(isdigit(*ptr)) ptr++; + + /* if we have only digits then conver it*/ + if (*ptr == '\0') { + int time = atoi(alarm_period); + if (time > 0) + ret_val = time; /* Alarm period in seconds */ + } + } + return ret_val; +} + +/***************************************************************************** + * Function: health_poll_worker + * + * Description: This is the routine registered to system timer for updating + * the throughput values for all the clients and its respective osc(s). + * + * Input: 'registration_number` value obtained during the alarm registration + * 'clientarg' pointing to user defined data type. + * Output: void + *****************************************************************************/ + +void health_poll_worker(unsigned int registration_number, void *clientarg) +{ + health_entry_parser(); + + /* Register the function again to call after lustre_alarm_period */ + if (!snmp_alarm_register(g_poll_interval_seconds, 0, health_poll_worker, NULL)) { + report("%s %s:line %d %s", __FILE__, __FUNCTION__, __LINE__, + "snmp_alarm_register failed"); + } +} + +/***************************************************************************** + * Function: health_entry_parser + * + * Description: This routine is called to parse the health_check entry + * and send traps + * Input: 'None + * Output: void + *****************************************************************************/ + + void health_entry_parser(void) +{ + FILE *fptr = NULL; + char string[MAX_LINE_SIZE]; + int b_seen_portals_catastrophe = 0; + const char *filename = g_health_check_test_file == 0 ? + LUSTRE_PATH FILENAME_SYSHEALTHCHECK : + g_health_check_test_file; + + /*DEBUGMSGTL(("lsnmpd","health_entry_parser(%s)\n",filename));*/ + + /* Open the file. Use the test file env variable if + there is one */ + fptr = fopen(filename,"r"); + + /* If the path is not found do nothing */ + if( NULL == fptr) + return; + + while( NULL != fgets(string, sizeof(string), fptr)){ + + /*DEBUGMSGTL(("lsnmpd","health_entry_parser() looking at = \'%s\'\n",string));*/ + + /* + * First handle the portals catastrophe + * Look for the string "LBUG" + */ + if(0 == strncmp(string,"LBUG",4)){ + /* + * If we haven't sent the catastrophe message yet + * send it now. And keep track that we've sent it + */ + if(!g_sent_portals_catastrophe){ + send_portals_catastrophe_trap("LBUG"); + g_sent_portals_catastrophe = 1; + } + b_seen_portals_catastrophe = 1; + } + + /* + * Now handle any of the OBD object failures + * look for "device reported unhealthy" + */ + else if(0 == strncmp(string,"device ",7)){ + char *obd_name = string+7; + char *space_after_obd_name; + + /* + * Now find the space after the obd name + * Again if there is no space we're in trouble + */ + space_after_obd_name = strchr(obd_name,' '); + if(space_after_obd_name == 0) + break; + + /* + * Null terminate the obd_name + */ + *space_after_obd_name = 0; + + DEBUGMSGTL(("lsnmpd","Looking at obd=%s\n",obd_name)); + + /* + * If we haven't sent a trap for this one + * then send it now + */ + if(is_obd_newly_unhealthy(obd_name)) + send_obd_unhealthy_trap(obd_name,"unhealthy"); + } + } + + /* If we don't find it reset the catastrope flag*/ + if(!b_seen_portals_catastrophe && g_sent_portals_catastrophe) + { + DEBUGMSGTL(("lsnmpd","LBUG has been cleared\n")); + g_sent_portals_catastrophe = 0; + } + + /* + * Any that weren't queried above are now unhealthy. + * Scan through and cleanup the newly healthy obds + */ + obd_unhealthy_scan(); + + fclose(fptr); +} + +/***************************************************************************** + * Function: send_portals_catastrophe_trap + * + * Description: Send the SNMP V2 trap + * + * Input: 'reason_string' the reason for the catastrope. + + * Output: none + *****************************************************************************/ + +void send_portals_catastrophe_trap(char *reason_string) +{ + /* + * Setup the trap variables. + * It's a linked list of netsnmp_variable_list items. + */ + netsnmp_variable_list var_trap[2]; + + DEBUGMSGTL(("lsnmpd","Sending portals catastrophe trap reason=%s\n",reason_string)); + + /* + * Setup the first variable in the trap data. + * Have it chain to another variable. + */ + var_trap[0].next_variable = &var_trap[1]; + + /*The "name" must be the standard snmp "trap" OID.*/ + var_trap[0].name = objid_snmptrap; + var_trap[0].name_length = sizeof(objid_snmptrap) / sizeof(oid); + + /*But the data contained in this variable, is an OID that is the trap OID.*/ + var_trap[0].type = ASN_OBJECT_ID; + var_trap[0].val.objid = lustre_portals_trap; + var_trap[0].val_len = sizeof(lustre_portals_trap); + + /* + * Setup the second variable in the trap data. + * It is the last in the chain so set next to NULL + */ + var_trap[1].next_variable = NULL; + + /*The "name" is the OID of the portals trap reason strong*/ + var_trap[1].name = lustre_portals_trap_string; + var_trap[1].name_length = sizeof(lustre_portals_trap_string) / sizeof(oid); + + /*And the data is a octet string, that contains the actually reason string*/ + var_trap[1].type = ASN_OCTET_STR; + var_trap[1].val.string = reason_string; + var_trap[1].val_len = strlen(reason_string); + + /*And now send off the trap*/ + send_v2trap(var_trap); +} + + +/***************************************************************************** + * Function: send_obd_unhealthy_trap + * + * Description: Send the SNMP V2 trap + * + * Input: 'obd_name' the name of the obd + * 'reason_string' the reason for the catastrope. + * Output: none + *****************************************************************************/ + +void send_obd_unhealthy_trap(char *obd_name,char *reason_string) +{ + /* + * Setup the trap variables. + * It's a linked list of netsnmp_variable_list items. + */ + netsnmp_variable_list var_trap[3]; + + DEBUGMSGTL(("lsnmpd","Sending OBD unhealthy trap obd=%s reason=%s\n",obd_name,reason_string)); + + /* + * Setup the first variable in the trap data. + * Have it chain to another variable. + */ + var_trap[0].next_variable = &var_trap[1]; + + /*The "name" must be the standard snmp "trap" OID.*/ + var_trap[0].name = objid_snmptrap; + var_trap[0].name_length = sizeof(objid_snmptrap) / sizeof(oid); + + /*But the data contained in this variable, is an OID that is the trap OID.*/ + var_trap[0].type = ASN_OBJECT_ID; + var_trap[0].val.objid = lustre_unhealthy_trap; + var_trap[0].val_len = sizeof(lustre_unhealthy_trap); + + /* + * Setup the second variable in the trap data. + * Have it chain to another variable. + */ + var_trap[1].next_variable = &var_trap[2];; + + /*The "name" is the OID of the portals trap reason strong*/ + var_trap[1].name = lustre_unhealthy_trap_device_name_string; + var_trap[1].name_length = sizeof(lustre_unhealthy_trap_device_name_string) / sizeof(oid); + + /*And the data is a octet string, that contains the actually reason strong*/ + var_trap[1].type = ASN_OCTET_STR; + var_trap[1].val.string = obd_name; + var_trap[1].val_len = strlen(obd_name); + + /* + * Setup the third variable in the trap data. + * It is the last in the chain so set next to NULL + */ + var_trap[2].next_variable = NULL; + + /*The "name" is the OID of the portals trap reason strong*/ + var_trap[2].name = lustre_unhealthy_trap_reason_string; + var_trap[2].name_length = sizeof(lustre_unhealthy_trap_reason_string) / sizeof(oid); + + /*And the data is a octet string, that contains the actually reason strong*/ + var_trap[2].type = ASN_OCTET_STR; + var_trap[2].val.string = reason_string; + var_trap[2].val_len = strlen(reason_string); + + /*And now send off the trap*/ + send_v2trap(var_trap); +} + + +/***************************************************************************** + * Function: is_obd_newly_unhealthy + * + * Description: Deterime if the obd is going from health->unhealth + * Also mark all unhealhy (new and old) as seen. + * + * Input: 'obd_name' the name of the obd + * + * Output: 1 if newly unhealthy 0 if previolsy unhealthy + *****************************************************************************/ + +int is_obd_newly_unhealthy(const char* obd_name) +{ + /*for all elements in g_obd_unhealthy_list*/ + obd_unhealthy_entry* walker; + obd_unhealthy_entry* entry; + int name_len; + + for(walker = g_obd_unhealthy_list; walker != 0; walker = walker->next) + { + /*If the names match*/ + if(0 == strcmp (walker->name,obd_name)) + { + /* Commented out because it was just to noisy! + * DEBUGMSGTL(("lsnmpd","obd %s was already unhealthy\n",obd_name)); + */ + + /*Mark the entry as seen, and return that it was previously unhealthy*/ + walker->seen =1; + return 0; + } + } + + DEBUGMSGTL(("lsnmpd","obd %s is now unhealthy\n",obd_name)); + + /*We didn't find an entry so we need to create a new one. */ + /*Calculate the obd_name length*/ + name_len = strlen(obd_name)+1; + + /*Allocate a new entry*/ + entry = malloc(sizeof(*entry) + name_len); + + /*Put this element at the front of the list*/ + entry->next = g_obd_unhealthy_list; + g_obd_unhealthy_list = entry; + + /*Mark it initially as seen*/ + entry->seen = 1; + + /*And copy the entry name*/ + memcpy(entry->name,obd_name,name_len); + + /*return this obd as newly unhealthy.*/ + return 1; +} + + +/***************************************************************************** + * Function: obd_unhealthy_scan + * + * Description: Deterime if any obd is going from unhealthy->healthy + * Any of the obds that weren't "seen" by the + * is_obd_newly_unhealthy() pass are now health so + * remove them from the lists + * Also clear all "seen" flags. + * + * Input: None + * Output: None + *****************************************************************************/ + +void obd_unhealthy_scan(void) +{ + /*fore all elements in g_obd_unhealthy_list*/ + obd_unhealthy_entry* walker = g_obd_unhealthy_list; + obd_unhealthy_entry* prev = 0; + while(walker != 0) + { + /*remove any that was not seen as unhealthy the last time*/ + if(walker->seen == 0) + { + /*Remove element from the list, but first fix up the walker pointer*/ + obd_unhealthy_entry* temp = walker; + + DEBUGMSGTL(("lsnmpd","obd %s is now healthy\n",walker->name)); + + walker = walker->next; + + /*Now adjust the pointers to effectively remove this entry*/ + if(prev == 0) + g_obd_unhealthy_list = walker; + else + prev->next = walker; + + /*And free the pointer. */ + free(temp); + /*walker and prev are correctly setup so we can go around the loop again.*/ + } + + /*Mark all other entries as NOT seen for next pass through*/ + else + { + walker->seen = 0; + /*Go onto the next entry*/ + prev = walker; + walker = walker->next; + } + } +} diff --git a/snmp/lustre-snmp-trap.h b/snmp/lustre-snmp-trap.h new file mode 100644 index 0000000..ce82324 --- /dev/null +++ b/snmp/lustre-snmp-trap.h @@ -0,0 +1,29 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (c) 2005 Cluster File Systems, Inc. + * Author: PJ Kirner + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre 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 Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef LUSTRE_SNMP_TRAP_H +#define LUSTRE_SNMP_TRAP_H + +extern void initilize_trap_handler(void); +extern void terminate_trap_handler(void); + +#endif diff --git a/snmp/lustre-snmp-util.c b/snmp/lustre-snmp-util.c new file mode 100644 index 0000000..8048f2d --- /dev/null +++ b/snmp/lustre-snmp-util.c @@ -0,0 +1,652 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (c) 2005 Cluster File Systems, Inc. + * Author: PJ Kirner + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre 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 Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * include important headers + */ + +#include +#include +#include + +/* + * include our .h file + */ + +#include +#include +#include +#include +#include +#include +#include +#include "lustre-snmp-util.h" + +/********************************************************************* + * Function: get_file_list + * + * Description: For the given valid directory path, returns the list + * all directories or files in that path. + * + * Input: 'dirname' the directory path. + * 'file_type' if this takes the value DIR_TYPE then + * returns the list of directories in that path. + * If its of type FILE_TYPE then returns the list of files + * in that path. + * 'count' pointer to number of elements returned in the + * return string. + * + * Output: List of directories/files in that path. + * + *********************************************************************/ + +char *get_file_list(const char *dirname, int file_type, uint32_t *count) +{ + + DIR *pdir = NULL; + struct dirent *pdirent = NULL; + int curr_offset = 0; + int byte_count = 0; + int file_count = 0; + char *ret_str = NULL; + char filename[MAX_PATH_SIZE]; + int cond1, cond2; + + if ((dirname == NULL) || ((pdir = opendir(dirname)) == NULL )) { + if (dirname == NULL) { + report("%s %s:line %d %s", __FILE__, __FUNCTION__, __LINE__, + "NULL directory is passed as parameter to funtion"); + } else { + report("%s %s:line %d Error in opening the dir %s", __FILE__, + __FUNCTION__, __LINE__, dirname); + } + if (count) + *count = 0; + return NULL; + } + + while (1) { + if ((pdirent = readdir(pdir)) == NULL) + break; + + /* Skip over '.' and '..' directores */ + if ((pdirent->d_name[0] == '.') || + !strcmp(pdirent->d_name, FILENAME_NUM_REF)) + continue; + + sprintf(filename, "%s/%s", dirname, pdirent->d_name); + cond1 = (file_type == FILE_TYPE) && is_directory(filename); + cond2 = (file_type == DIR_TYPE) && (!is_directory(filename)); + + if (cond1 || cond2) + continue; + + /* Calculate the number of bytes for this new entry.*/ + byte_count += strlen(pdirent->d_name) + 1; + file_count++; + } + if (count) + *count = file_count; + + if (file_count != 0) { + + /* need one extra one for the finall NULL terminator*/ + if ((ret_str = (char *) malloc(byte_count + 1)) == NULL) { + report("get_file_list() failed to malloc(%d)",byte_count+1); + closedir(pdir); + return NULL; + } + + rewinddir(pdir); + + while (file_count != 0) { + if ((pdirent = readdir(pdir)) == NULL) + break; + + if ((pdirent->d_name[0] == '.') || + !strcmp(pdirent->d_name, FILENAME_NUM_REF)) + continue; + + sprintf(filename, "%s/%s", dirname, pdirent->d_name); + cond1 = (file_type == FILE_TYPE) && is_directory(filename); + cond2 = (file_type == DIR_TYPE) && (!is_directory(filename)); + + if (cond1 || cond2) + continue; + + strcpy(ret_str + curr_offset, pdirent->d_name); + curr_offset = curr_offset + strlen(pdirent->d_name) + 1; + file_count--; + } + /* Put in the finall null terminator*/ + ret_str[byte_count] = '\0'; + } + closedir(pdir); + return ret_str; +} + + +/********************************************************************* + * Function: is_directory + * + * Description: Checks if given filename is a directory or not. + * all directories or files in that path. + * + * Input: 'filename' the directory path to be checked. + * + * Output: Returns 1 if its a directory else 0. + * + *********************************************************************/ + +int is_directory(const char *filename) +{ + + struct stat statf; + int result; + + result = stat(filename, &statf); + return ((result == SUCCESS) && (statf.st_mode & S_IFDIR)); +} + +/********************************************************************* + * Function: read_string + * + * Description: For the given valid file path, reads the data in + * that file. + * + * Input: 'filepath' the file whose data is to be accessed. + * 'lustre_var' the data from the file is read into + * this variable, returned to the requestor. + * 'var_max_size' the max size of the string + * 'report_error' boolean if error should be reported on + * missing filepath + * + * Output: Returns SUCCESS if read successfully from file else + * returns ERROR. + *********************************************************************/ + +int read_string(const char *filepath, char *lustre_var, size_t var_max_size) +{ + FILE *fptr = NULL; + int len = 0; + int ret_val = SUCCESS; + int report_error = 1; + + if ((filepath == NULL) || (lustre_var == NULL)) { + report("%s %s:line %d %s", __FILE__, __FUNCTION__, __LINE__, + "Input parameter is NULL"); + ret_val = ERROR; + } else { + fptr = fopen(filepath, "r"); + + if (fptr == NULL) { + if(report_error) + report("%s %s:line %d Unable to open the file %s", __FILE__, + __FUNCTION__, __LINE__, filepath); + ret_val = ERROR; + } else { + if (fgets(lustre_var, var_max_size, fptr) == NULL) { + report("%s %s:line %d read failed for file %s", __FILE__, + __FUNCTION__, __LINE__, filepath); + ret_val = ERROR; + } else { + len = strlen(lustre_var); + /* + Last char is EOF, before string ends, + so '\0' is moved to last but one. + */ + lustre_var[len-1] = lustre_var[len]; + } + fclose(fptr); + } + } + return ret_val; +} + +/************************************************************************** + * Function: lustrefs_ctrl + * + * Description: Execute /etc/init.d/lustre script for starting, + * stopping and restarting Lustre services in child process. + * + * Input: Start/Stop/Restart Command Number. + * Output: Returns void + * + **************************************************************************/ + +void lustrefs_ctrl(int command) +{ + char *cmd[3]; + + cmd[0] = LUSTRE_SERVICE; + switch (command) { + case ONLINE: + cmd[1] = "start"; + break; + case OFFLINE: + cmd[1] = "stop"; + break; + case RESTART: + cmd[1] = "restart"; + break; + default: + return; + } + + cmd[2] = (char *)0; + + if (fork() == 0) { + execvp(cmd[0], cmd); + report("failed to execvp(\'%s %s\')",cmd[0],cmd[1]); + } + return; +} + +/***************************************************************************** + * Function: get_sysstatus + * + * Description: Read /var/lustre/sysStatus file, and based on file contents + * return the status of Lustre services. + * + * Input: void + * Output: Return ONLINE/OFFLINE/ONLINE PENDING/OFFLINE PENDING status + * values. + * + ****************************************************************************/ + +int get_sysstatus(void) +{ + FILE *fptr = NULL; + int len = 0; + int ret_val = ERROR ; + char sys_status[50] = {0}; + + if(SUCCESS == read_string(FILENAME_SYS_STATUS,sys_status,sizeof(sys_status))) + { + if (memcmp(sys_status, STR_ONLINE_PENDING,strlen(STR_ONLINE_PENDING)) == 0) + ret_val = ONLINE_PENDING; + else if (memcmp(sys_status, STR_ONLINE, strlen(STR_ONLINE)) == 0) + ret_val = ONLINE; + else if (memcmp(sys_status, STR_OFFLINE_PENDING,strlen(STR_OFFLINE_PENDING)) == 0) + ret_val = OFFLINE_PENDING; + else if (memcmp(sys_status, STR_OFFLINE, strlen(STR_OFFLINE)) == 0) + ret_val = OFFLINE; + else + report("%s %s:line %d Bad Contents in file %s \'%s\'", __FILE__, + __FUNCTION__, __LINE__, FILENAME_SYS_STATUS,sys_status); + } + return ret_val; +} + + +/***************************************************************************** + * Function: read_ulong + * + * Description: Read long values from lproc and copy to the location + * pointed by input parameter. + * + * Input: file path, and pointer for data to be copied + * + * Output: Return ERROR or SUCCESS. + * + ****************************************************************************/ + +int read_ulong(const char *file_path, unsigned long *valuep) +{ + char file_data[MAX_LINE_SIZE]; + int ret_val; + + if ((ret_val = read_string(file_path, file_data,sizeof(file_data))) == SUCCESS){ + *valuep = strtoul(file_data,NULL,10); + } + return ret_val; +} + +/***************************************************************************** + * Function: read_counter64 + * + * Description: Read counter64 values from lproc and copy to the location + * pointed by input parameter. + * + * Input: file path, and pointer for data to be copied + * + * Output: Return ERROR or SUCCESS. + * + ****************************************************************************/ + +int read_counter64(const char *file_path, counter64 *c64,int factor) +{ + char file_data[MAX_LINE_SIZE]; + int ret_val; + unsigned long long tmp = 0; + + if ((ret_val = read_string(file_path, file_data,sizeof(file_data))) == SUCCESS) { + tmp = atoll(file_data) * factor; + c64->low = (ulong) (0x0FFFFFFFF & tmp); + tmp >>= 32; /* Shift right by 4 bytes */ + c64->high = (ulong) (0x0FFFFFFFF & tmp); + } + return ret_val; +} + +/***************************************************************************** + * Function: get_nth_entry_from_list + * + * Description: Find the n'th entry from a null terminated list of string + * + * Input: dir_list - the list + * num - the number of elements in the list + * index - the index we are looking for + * + * Output: Return NULL on failure, or the string name on success. + * + ****************************************************************************/ + +const char *get_nth_entry_from_list(const char* dir_list,int num,int index) +{ + int i; + int cur_ptr = 0; + for(i=0;i= num){ + report("deviceindex=%d exceeds number of elements=%d",deviceindex,num); + goto cleanup_and_exit; + } + + /* + * Fetch the object name from the list + */ + obj_name = get_nth_entry_from_list(dir_list,num,deviceindex); + if(obj_name == NULL){ + /* + * Note this should never really happen because we check deviceindex >=num + * above. And dir_list should be consitent with num + * but just in case... + */ + report("object name not found in list",deviceindex,num); + goto cleanup_and_exit; + } + + /* + * Find the matching magic - or the end of the list + */ + while(ptable[i].magic != vp->magic && ptable[i].magic != 0) + i++; + + /* + * If we didn't find a matching entry return + */ + if(ptable[i].magic==0) + goto cleanup_and_exit; + + /* + * If the name is NULL is a special case and + * just just pass the obj_name as the file_path + * otherwise we create a file path from the given components + */ + if(ptable[i].name != 0){ + char file_path[MAX_PATH_SIZE]; + sprintf(file_path, "%s%s/%s",path,obj_name,ptable[i].name); + ret_val = ptable[i].fhandler(file_path,var_len); + } + else + ret_val = ptable[i].fhandler(obj_name,var_len); + +cleanup_and_exit: + free(dir_list); + return ret_val; +}; + diff --git a/snmp/lustre-snmp-util.h b/snmp/lustre-snmp-util.h new file mode 100644 index 0000000..087e8cc --- /dev/null +++ b/snmp/lustre-snmp-util.h @@ -0,0 +1,197 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (c) 2005 Cluster File Systems, Inc. + * Author: PJ Kirner + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre 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 Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef LUSTRE_SNMP_UTIL_H +#define LUSTRE_SNMP_UTIL_H + +/* + * Definitions of magic values + */ + +#define SYSVERSION 20 +#define SYSKERNELVERSION 21 +#define SYSHEALTHCHECK 22 +#define SYSSTATUS 23 + +#define OSDNUMBER 30 +#define OSDUUID 31 +#define OSDCOMMONNAME 32 +#define OSDCAPACITY 33 +#define OSDFREECAPACITY 34 +#define OSDOBJECTS 35 +#define OSDFREEOBJECTS 36 + +#define OSCNUMBER 40 +#define OSCUUID 41 +#define OSCCOMMONNAME 42 +#define OSCOSTSERVERUUID 43 +#define OSCCAPACITY 44 +#define OSCFREECAPACITY 45 +#define OSCOBJECTS 46 +#define OSCFREEOBJECTS 47 + +#define MDDNUMBER 50 +#define MDDUUID 51 +#define MDDCOMMONNAME 52 +#define MDDCAPACITY 53 +#define MDDFREECAPACITY 54 +#define MDDFILES 55 +#define MDDFREEFILES 56 + +#define MDCNUMBER 60 +#define MDCUUID 61 +#define MDCCOMMONNAME 62 +#define MDCMDSSERVERUUID 63 +#define MDCCAPACITY 64 +#define MDCFREECAPACITY 65 +#define MDCOBJECTS 66 +#define MDCFREEOBJECTS 67 + +#define CLIMOUNTNUMBER 70 +#define CLIUUID 71 +#define CLICOMMONNAME 72 +#define CLIMDCUUID 73 +#define CLIMDCCOMMONNAME 74 +#define CLIUSESLOV 75 +#define CLILOVUUID 76 +#define CLILOVCOMMONNAME 77 + +#define LOVNUMBER 80 +#define LOVUUID 81 +#define LOVCOMMONNAME 82 +#define LOVNUMOBD 83 +#define LOVNUMACTIVEOBD 84 +#define LOVCAPACITY 85 +#define LOVFREECAPACITY 86 +#define LOVFILES 87 +#define LOVFREEFILES 88 +#define LOVSTRIPECOUNT 89 +#define LOVSTRIPEOFFSET 90 +#define LOVSTRIPESIZE 91 +#define LOVSTRIPETYPE 92 + +#define LDLMNUMBER 100 +#define LDLMNAMESPACE 101 +#define LDLMLOCKCOUNT 102 +#define LDLMUNUSEDLOCKCOUNT 103 +#define LDLMRESOURCECOUNT 104 + +/* Defining the proc paths for Lustre file system */ +#define LUSTRE_PATH "/proc/fs/lustre/" +#define OSD_PATH LUSTRE_PATH "obdfilter/" +#define OSC_PATH LUSTRE_PATH "osc/" +#define MDS_PATH LUSTRE_PATH "mds/" +#define MDC_PATH LUSTRE_PATH "mdc/" +#define CLIENT_PATH LUSTRE_PATH "llite/" +#define LOV_PATH LUSTRE_PATH "lov/" +#define LDLM_PATH LUSTRE_PATH "ldlm/namespaces/" + +/* Common procfs file entries that are refrenced in mulitple locations*/ +#define FILENAME_SYSHEALTHCHECK "health_check" +#define FILENAME_SYS_STATUS "/var/lustre/sysStatus" + +#define FILENAME_NUM_REF "num_refs" +#define FILENAME_UUID "uuid" +#define FILENAME_COMMON_NAME "common_name" +#define FILENAME_KBYTES_TOTAL "kbytestotal" +#define FILENAME_KBYTES_FREE "kbytesfree" +#define FILENAME_FILES_TOTAL "filestotal" +#define FILENAME_FILES_FREE "filesfree" + +/* strings which the file /var/lustre/sysStatus can hold */ +#define STR_ONLINE "online" +#define STR_ONLINE_PENDING "online pending" +#define STR_OFFLINE "offline" +#define STR_OFFLINE_PENDING "offline pending" + + +/* Script required for starting/stopping lustre services */ +#define LUSTRE_SERVICE "/etc/init.d/lustre" + +#define MIN_LEN(val1,val2) (((val1)>(val2))?(val2):(val1)) + +/* The max size of a lustre procfs path name*/ +#define MAX_PATH_SIZE 512 + +/* The max size of a string read from procfs */ +#define MAX_LINE_SIZE 512 + +/* Types passed to get_file_list() */ +#define DIR_TYPE 1 +#define FILE_TYPE 0 + +/* Defining return values */ +#define SUCCESS 0 +#define ERROR -1 + +typedef struct counter64 counter64; + +typedef enum { + ONLINE = 1, + OFFLINE, + ONLINE_PENDING, + OFFLINE_PENDING, + RESTART +} lustre_sysstatus; + +/* File operation related functions */ +char *get_file_list(const char *dirname, int file_type, uint32_t *count); +extern int is_directory(const char *filename); +extern int read_string(const char *filepath, char *lustre_var,size_t var_size); +int read_counter64(const char *file_path, counter64 *c64,int factor); +int read_ulong(const char *file_path,unsigned long* valuep); + +/* Start/Stop/Restart Lustre Services */ +extern void lustrefs_ctrl(int command); +extern int get_sysstatus(); + +extern void report(const char *fmt, ...); + +/* Table Driven SNMP OID Handler support*/ +typedef unsigned char* (*f_oid_handler_t)( + const char* file_path, + size_t *var_len); + +struct oid_table +{ + int magic; /*The magic number*/ + const char *name; /*The procfs name*/ + f_oid_handler_t fhandler; /*The handler */ +}; + +unsigned char* oid_table_ulong_handler(const char* file_path,size_t *var_len); +unsigned char* oid_table_c64_handler(const char* file_path,size_t *var_len); +unsigned char* oid_table_c64_kb_handler(const char* file_path,size_t *var_len); +unsigned char* oid_table_obj_name_handler(const char* file_path,size_t *var_len); +unsigned char* oid_table_string_handler(const char* file_path,size_t *var_len); +unsigned char* oid_table_is_directory_handler(const char* file_path,size_t *var_len); +unsigned char * + var_genericTable(struct variable *vp, + oid *name, + size_t *length, + int exact, + size_t *var_len, + WriteMethod **write_method, + const char *path, + struct oid_table *ptable); + +#endif /* LUSTRE_SNMP_UTIL_H */ diff --git a/snmp/lustre-snmp.c b/snmp/lustre-snmp.c new file mode 100644 index 0000000..0de2c4d --- /dev/null +++ b/snmp/lustre-snmp.c @@ -0,0 +1,601 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (c) 2005 Cluster File Systems, Inc. + * Author: PJ Kirner + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre 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 Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include "lustre-snmp.h" + +/* + * clusterFileSystems_variables_oid: + * this is the top level oid that we want to register under. This + * is essentially a prefix, with the suffix appearing in the + * variable below. + */ + + +oid clusterFileSystems_variables_oid[] = { 1,3,6,1,4,1,13140 }; + + +/* + * variable7 clusterFileSystems_variables: + * this variable defines function callbacks and type return information + * for the clusterFileSystems mib section + */ + + +struct variable7 clusterFileSystems_variables[] = { +/* magic number , variable type , ro/rw , callback fn , L, oidsuffix */ + + /* sytemInformation 2.1.1. */ + { SYSVERSION , ASN_OCTET_STR , RONLY , var_clusterFileSystems, 4, { 2,1,1,1 } }, + { SYSKERNELVERSION , ASN_OCTET_STR , RONLY , var_clusterFileSystems, 4, { 2,1,1,2 } }, + { SYSHEALTHCHECK , ASN_OCTET_STR , RONLY , var_clusterFileSystems, 4, { 2,1,1,3 } }, + { SYSSTATUS , ASN_INTEGER , RWRITE, var_clusterFileSystems, 4, { 2,1,1,4 } }, + + /* objectStorageTargets 2.1.2 */ + { OSDNUMBER , ASN_UNSIGNED , RONLY , var_clusterFileSystems, 4, { 2,1,2,1 } }, + + /* objectStorageTargets.osdTable.osdEntry 2.1.2.2.1 */ + { OSDUUID , ASN_OCTET_STR , RONLY , var_osdTable, 6, { 2,1,2,2,1,2 } }, + { OSDCOMMONNAME , ASN_OCTET_STR , RONLY , var_osdTable, 6, { 2,1,2,2,1,3 } }, + { OSDCAPACITY , ASN_COUNTER64 , RONLY , var_osdTable, 6, { 2,1,2,2,1,4 } }, + { OSDFREECAPACITY , ASN_COUNTER64 , RONLY , var_osdTable, 6, { 2,1,2,2,1,5 } }, + { OSDOBJECTS , ASN_COUNTER64 , RONLY , var_osdTable, 6, { 2,1,2,2,1,6 } }, + { OSDFREEOBJECTS , ASN_COUNTER64 , RONLY , var_osdTable, 6, { 2,1,2,2,1,7 } }, + + /* objectStorageClients 2.1.3 */ + { OSCNUMBER , ASN_UNSIGNED , RONLY , var_clusterFileSystems, 4, { 2,1,3,1 } }, + + /* objectStorageClients.oscTable.oscEntry 2.1.3.2.1 */ + { OSCUUID , ASN_OCTET_STR , RONLY , var_oscTable, 6, { 2,1,3,2,1,2 } }, + { OSCCOMMONNAME , ASN_OCTET_STR , RONLY , var_oscTable, 6, { 2,1,3,2,1,3 } }, + { OSCOSTSERVERUUID , ASN_OCTET_STR , RONLY , var_oscTable, 6, { 2,1,3,2,1,4 } }, + { OSCCAPACITY , ASN_COUNTER64 , RONLY , var_oscTable, 6, { 2,1,3,2,1,5 } }, + { OSCFREECAPACITY , ASN_COUNTER64 , RONLY , var_oscTable, 6, { 2,1,3,2,1,6 } }, + { OSCOBJECTS , ASN_COUNTER64 , RONLY , var_oscTable, 6, { 2,1,3,2,1,7 } }, + { OSCFREEOBJECTS , ASN_COUNTER64 , RONLY , var_oscTable, 6, { 2,1,3,2,1,8 } }, + + + /* metaDataServers 2.1.4 */ + { MDDNUMBER , ASN_UNSIGNED , RONLY , var_clusterFileSystems, 4, { 2,1,4,1 } }, + + /* metaDataServers.mddTable.mddEntry 2.1.4.2.1 */ + { MDDUUID , ASN_OCTET_STR , RONLY , var_mdsTable, 6, { 2,1,4,2,1,2 } }, + { MDDCOMMONNAME , ASN_OCTET_STR , RONLY , var_mdsTable, 6, { 2,1,4,2,1,3 } }, + { MDDCAPACITY , ASN_COUNTER64 , RONLY , var_mdsTable, 6, { 2,1,4,2,1,4 } }, + { MDDFREECAPACITY , ASN_COUNTER64 , RONLY , var_mdsTable, 6, { 2,1,4,2,1,5 } }, + { MDDFILES , ASN_COUNTER64 , RONLY , var_mdsTable, 6, { 2,1,4,2,1,6 } }, + { MDDFREEFILES , ASN_COUNTER64 , RONLY , var_mdsTable, 6, { 2,1,4,2,1,7 } }, + + /* metaDataClients 2.1.5 */ + { MDCNUMBER , ASN_UNSIGNED , RONLY , var_clusterFileSystems, 4, { 2,1,5,1 } }, + + /* metaDataClients.mdcTable.mdcEntry 2.1.5.2.1 */ + { MDCUUID , ASN_OCTET_STR , RONLY , var_mdcTable, 6, { 2,1,5,2,1,2 } }, + { MDCCOMMONNAME , ASN_OCTET_STR , RONLY , var_mdcTable, 6, { 2,1,5,2,1,3 } }, + { MDCMDSSERVERUUID , ASN_OCTET_STR , RONLY , var_mdcTable, 6, { 2,1,5,2,1,4 } }, + { MDCCAPACITY , ASN_COUNTER64 , RONLY , var_mdcTable, 6, { 2,1,5,2,1,5 } }, + { MDCFREECAPACITY , ASN_COUNTER64 , RONLY , var_mdcTable, 6, { 2,1,5,2,1,6 } }, + { MDCOBJECTS , ASN_COUNTER64 , RONLY , var_mdcTable, 6, { 2,1,5,2,1,7 } }, + { MDCFREEOBJECTS , ASN_COUNTER64 , RONLY , var_mdcTable, 6, { 2,1,5,2,1,8 } }, + + /* lustreClients 2.1.6 */ + { CLIMOUNTNUMBER , ASN_UNSIGNED , RONLY , var_clusterFileSystems, 4, { 2,1,6,1 } }, + + /* lustreClients.cliMountTable.cliMountEntry 2.1.6.2.1 */ + { CLIUUID , ASN_OCTET_STR , RONLY , var_cliTable, 6, { 2,1,6,2,1,2 } }, + { CLICOMMONNAME , ASN_OCTET_STR , RONLY , var_cliTable, 6, { 2,1,6,2,1,3 } }, + { CLIMDCUUID , ASN_OCTET_STR , RONLY , var_cliTable, 6, { 2,1,6,2,1,4 } }, + { CLIMDCCOMMONNAME , ASN_OCTET_STR , RONLY , var_cliTable, 6, { 2,1,6,2,1,5 } }, + { CLIUSESLOV , ASN_INTEGER , RONLY , var_cliTable, 6, { 2,1,6,2,1,6 } }, + { CLILOVUUID , ASN_OCTET_STR , RONLY , var_cliTable, 6, { 2,1,6,2,1,7 } }, + { CLILOVCOMMONNAME , ASN_OCTET_STR , RONLY , var_cliTable, 6, { 2,1,6,2,1,8 } }, + + /* logicalObjectVolume 2.1.7 */ + { LOVNUMBER , ASN_UNSIGNED , RONLY , var_clusterFileSystems, 4, { 2,1,7,1 } }, + + /* logicalObjectVolume.osdTable.lovTable 2.1.2.2.1 */ + { LOVUUID , ASN_OCTET_STR , RONLY , var_lovTable, 6, { 2,1,7,2,1,2 } }, + { LOVCOMMONNAME , ASN_OCTET_STR , RONLY , var_lovTable, 6, { 2,1,7,2,1,3 } }, + { LOVNUMOBD , ASN_UNSIGNED , RONLY , var_lovTable, 6, { 2,1,7,2,1,4 } }, + { LOVNUMACTIVEOBD , ASN_UNSIGNED , RONLY , var_lovTable, 6, { 2,1,7,2,1,5 } }, + { LOVCAPACITY , ASN_COUNTER64 , RONLY , var_lovTable, 6, { 2,1,7,2,1,6 } }, + { LOVFREECAPACITY , ASN_COUNTER64 , RONLY , var_lovTable, 6, { 2,1,7,2,1,7 } }, + { LOVFILES , ASN_COUNTER64 , RONLY , var_lovTable, 6, { 2,1,7,2,1,8 } }, + { LOVFREEFILES , ASN_COUNTER64 , RONLY , var_lovTable, 6, { 2,1,7,2,1,9 } }, + { LOVSTRIPECOUNT , ASN_UNSIGNED , RONLY , var_lovTable, 6, { 2,1,7,2,1,10} }, + { LOVSTRIPEOFFSET , ASN_UNSIGNED , RONLY , var_lovTable, 6, { 2,1,7,2,1,11} }, + { LOVSTRIPESIZE , ASN_UNSIGNED , RONLY , var_lovTable, 6, { 2,1,7,2,1,12} }, + { LOVSTRIPETYPE , ASN_UNSIGNED , RONLY , var_lovTable, 6, { 2,1,7,2,1,13} }, + + /* lustreLDLM 2.1.8 */ + { LDLMNUMBER , ASN_UNSIGNED , RONLY , var_clusterFileSystems, 4, { 2,1,8,1 } }, + + /* lustreLDLM.ldlmTable.ldlmEntry 2.1.8.2.1 */ + { LDLMNAMESPACE , ASN_OCTET_STR , RONLY , var_ldlmTable, 6, { 2,1,8,2,1,2 } }, + { LDLMLOCKCOUNT , ASN_UNSIGNED , RONLY , var_ldlmTable, 6, { 2,1,8,2,1,3 } }, + { LDLMUNUSEDLOCKCOUNT , ASN_UNSIGNED , RONLY , var_ldlmTable, 6, { 2,1,8,2,1,4 } }, + { LDLMRESOURCECOUNT , ASN_UNSIGNED , RONLY , var_ldlmTable, 6, { 2,1,8,2,1,5 } }, + +}; + +/***************************************************************************** + * Function: init_cfsNetSNMPPlugin + * + * Description: Called when the agent starts up + * + * Input: void + * + * Output: None + * + ****************************************************************************/ + +void init_lustresnmp(void) { + + /* register ourselves with the agent to handle our mib tree */ + REGISTER_MIB("clusterFileSystems", clusterFileSystems_variables, variable7, + clusterFileSystems_variables_oid); + + initilize_trap_handler(); + + DEBUGMSGTL(("lsnmpd", "%s %s \n", __FUNCTION__, "Initialization Done")); +} + +/***************************************************************************** + * Function: deinit_cfsNetSNMPPlugin + * + * Description: Called when the agent terminates up + * + * Input: void + * + * Output: None + * + ****************************************************************************/ + +void deinit_lustresnmp(void) { + + /* deregister ourselves with the agent */ + unregister_mib(clusterFileSystems_variables_oid, + sizeof(clusterFileSystems_variables_oid)/sizeof(clusterFileSystems_variables_oid)); + + terminate_trap_handler(); + + DEBUGMSGTL(("lsnmpd", "%s %s \n", __FUNCTION__, "Termination Done")); +} + +/***************************************************************************** + * Function: var_clusterFileSystems + * + ****************************************************************************/ +unsigned char * +var_clusterFileSystems(struct variable *vp, + oid *name, + size_t *length, + int exact, + size_t *var_len, + WriteMethod **write_method) +{ + + + /* variables we may use later */ + static long long_ret; + static u_long ulong_ret; + static unsigned char string[SPRINT_MAX_LEN]; + char file_path[MAX_PATH_SIZE]; + uint32_t num; + char *dir_list; + + if (header_generic(vp,name,length,exact,var_len,write_method) + == MATCH_FAILED ) + return NULL; + + + /* + * this is where we do the value assignments for the mib results. + */ + switch(vp->magic) { + + case SYSVERSION: + sprintf(file_path, "%s%s", LUSTRE_PATH,"version"); + if( SUCCESS != read_string(file_path, string,sizeof(string))) + return NULL; + *var_len = strlen(string); + return (unsigned char *) string; + + case SYSKERNELVERSION: + sprintf(file_path, "%s%s", LUSTRE_PATH,"kernel_version"); + if( SUCCESS != read_string(file_path, string,sizeof(string))) + return NULL; + *var_len = strlen(string); + return (unsigned char *) string; + + case SYSHEALTHCHECK: + sprintf(file_path, "%s%s", LUSTRE_PATH,FILENAME_SYSHEALTHCHECK); + if( SUCCESS != read_string(file_path, string,sizeof(string))) + return NULL; + *var_len = strlen(string); + return (unsigned char *) string; + + case SYSSTATUS: + *write_method = write_sysStatus; + long_ret = (long) get_sysstatus(); + if (long_ret != ERROR) + return (unsigned char *) &long_ret; + return NULL; + + case OSDNUMBER: + if( 0 == (dir_list = get_file_list(OSD_PATH, DIR_TYPE, &num))) + return NULL; + DEBUGMSGTL(("lsnmpd","num(%s)=%d\n",OSD_PATH,num)); + ulong_ret = num; + free(dir_list); + return (unsigned char *) &ulong_ret; + + case OSCNUMBER: + if( 0 == (dir_list = get_file_list(OSC_PATH, DIR_TYPE, &num))) + return NULL; + DEBUGMSGTL(("lsnmpd","num(%s)=%d\n",OSC_PATH,num)); + ulong_ret = num; + free(dir_list); + return (unsigned char *) &ulong_ret; + + case MDDNUMBER: + if( 0 == (dir_list = get_file_list(MDS_PATH, DIR_TYPE, &num))) + return NULL; + DEBUGMSGTL(("lsnmpd","num(%s)=%d\n",MDS_PATH,num)); + ulong_ret = num; + free(dir_list); + return (unsigned char *) &ulong_ret; + + case MDCNUMBER: + if( 0 == (dir_list = get_file_list(MDC_PATH, DIR_TYPE, &num))) + return NULL; + DEBUGMSGTL(("lsnmpd","num(%s)=%d\n",MDC_PATH,num)); + ulong_ret = num; + free(dir_list); + return (unsigned char *) &ulong_ret; + + case CLIMOUNTNUMBER: + if( 0 == (dir_list = get_file_list(CLIENT_PATH, DIR_TYPE, &num))) + return NULL; + DEBUGMSGTL(("lsnmpd","num(%s)=%d\n",CLIENT_PATH,num)); + ulong_ret = num; + free(dir_list); + return (unsigned char *) &ulong_ret; + + case LOVNUMBER: + if( 0 == (dir_list = get_file_list(LOV_PATH, DIR_TYPE, &num))) + return NULL; + DEBUGMSGTL(("lsnmpd","num(%s)=%d\n",LOV_PATH,num)); + ulong_ret = num; + free(dir_list); + return (unsigned char *) &ulong_ret; + + case LDLMNUMBER: + if( 0 == (dir_list = get_file_list(LDLM_PATH, DIR_TYPE, &num))) + return NULL; + DEBUGMSGTL(("lsnmpd","num(%s)=%d\n",LDLM_PATH,num)); + ulong_ret = num; + free(dir_list); + return (unsigned char *) &ulong_ret; + + default: + ERROR_MSG(""); + } + return NULL; +} + +struct oid_table osd_table[] = +{ + { OSDUUID,FILENAME_UUID,oid_table_string_handler}, + { OSDCOMMONNAME,0,oid_table_obj_name_handler}, + { OSDCAPACITY,FILENAME_KBYTES_TOTAL, oid_table_c64_kb_handler}, + { OSDFREECAPACITY,FILENAME_KBYTES_FREE, oid_table_c64_kb_handler}, + { OSDOBJECTS,FILENAME_FILES_TOTAL, oid_table_c64_kb_handler}, + { OSDFREEOBJECTS,FILENAME_FILES_FREE, oid_table_c64_kb_handler}, + { 0,0,0 } /*End of table*/ +}; + + +/***************************************************************************** + * Function: var_osdTable + * + ****************************************************************************/ +unsigned char * +var_osdTable(struct variable *vp, + oid *name, + size_t *length, + int exact, + size_t *var_len, + WriteMethod **write_method) +{ + return var_genericTable(vp,name,length,exact,var_len,write_method, + OSD_PATH,osd_table); +} + +struct oid_table osc_table[] = +{ + { OSCUUID,FILENAME_UUID,oid_table_string_handler}, + { OSCCOMMONNAME,0,oid_table_obj_name_handler}, + { OSCOSTSERVERUUID,"ost_server_uuid",oid_table_string_handler}, + { OSCCAPACITY,FILENAME_KBYTES_TOTAL, oid_table_c64_kb_handler}, + { OSCFREECAPACITY,FILENAME_KBYTES_FREE, oid_table_c64_kb_handler}, + { OSCOBJECTS,FILENAME_FILES_TOTAL, oid_table_c64_kb_handler}, + { OSCFREEOBJECTS,FILENAME_FILES_FREE, oid_table_c64_kb_handler}, + { 0,0,0 } /*End of table*/ +}; + +/***************************************************************************** + * Function: var_oscTable + * + ****************************************************************************/ +unsigned char * +var_oscTable(struct variable *vp, + oid *name, + size_t *length, + int exact, + size_t *var_len, + WriteMethod **write_method) +{ + return var_genericTable(vp,name,length,exact,var_len,write_method, + OSC_PATH,osc_table); +} + +struct oid_table mds_table[] = +{ + { MDDUUID,FILENAME_UUID,oid_table_string_handler}, + { MDDCOMMONNAME,0,oid_table_obj_name_handler}, + { MDDCAPACITY,FILENAME_KBYTES_TOTAL, oid_table_c64_kb_handler}, + { MDDFREECAPACITY,FILENAME_KBYTES_FREE, oid_table_c64_kb_handler}, + { MDDFILES,FILENAME_FILES_TOTAL, oid_table_c64_kb_handler}, + { MDDFREEFILES,FILENAME_FILES_FREE, oid_table_c64_kb_handler}, + { 0,0,0 } /*End of table*/ +}; + +/***************************************************************************** + * Function: var_mdsTable + * + ****************************************************************************/ +unsigned char * +var_mdsTable(struct variable *vp, + oid *name, + size_t *length, + int exact, + size_t *var_len, + WriteMethod **write_method) +{ + return var_genericTable(vp,name,length,exact,var_len,write_method, + MDS_PATH,mds_table); +} + +struct oid_table mdc_table[] = +{ + { MDCUUID,FILENAME_UUID,oid_table_string_handler}, + { MDCCOMMONNAME,0,oid_table_obj_name_handler}, + { MDCMDSSERVERUUID,"mds_server_uuid",oid_table_string_handler}, + { MDCCAPACITY,FILENAME_KBYTES_TOTAL, oid_table_c64_kb_handler}, + { MDCFREECAPACITY,FILENAME_KBYTES_FREE, oid_table_c64_kb_handler}, + { MDCOBJECTS,FILENAME_FILES_TOTAL, oid_table_c64_kb_handler}, + { MDCFREEOBJECTS,FILENAME_FILES_FREE, oid_table_c64_kb_handler}, + { 0,0,0 } /*End of table*/ +}; + + +/***************************************************************************** + * Function: var_mdcTable + * + ****************************************************************************/ +unsigned char * +var_mdcTable(struct variable *vp, + oid *name, + size_t *length, + int exact, + size_t *var_len, + WriteMethod **write_method) +{ + return var_genericTable(vp,name,length,exact,var_len,write_method, + MDC_PATH,mdc_table); +} + + +struct oid_table cli_table[] = +{ + { CLIUUID,FILENAME_UUID,oid_table_string_handler}, + { CLICOMMONNAME,0,oid_table_obj_name_handler}, + { CLIMDCUUID,"mdc/" FILENAME_UUID,oid_table_string_handler}, + { CLIMDCCOMMONNAME,"mdc/" FILENAME_COMMON_NAME,oid_table_string_handler}, + { CLIUSESLOV,"lov/",oid_table_is_directory_handler}, + { CLILOVUUID,"lov/" FILENAME_UUID,oid_table_string_handler}, + { CLILOVCOMMONNAME,"lov/" FILENAME_COMMON_NAME,oid_table_string_handler}, + { 0,0,0 } /*End of table*/ +}; + +/***************************************************************************** + * Function: var_cliTable + * + ****************************************************************************/ +unsigned char * +var_cliTable(struct variable *vp, + oid *name, + size_t *length, + int exact, + size_t *var_len, + WriteMethod **write_method) +{ + return var_genericTable(vp,name,length,exact,var_len,write_method, + CLIENT_PATH,cli_table); +} + + +struct oid_table lov_table[] = +{ + { LOVUUID,FILENAME_UUID,oid_table_string_handler}, + { LOVCOMMONNAME,0,oid_table_obj_name_handler}, + { LOVNUMOBD,"numobd", oid_table_ulong_handler}, + { LOVNUMACTIVEOBD,"activeobd", oid_table_ulong_handler}, + { LOVCAPACITY,FILENAME_KBYTES_TOTAL, oid_table_c64_kb_handler}, + { LOVFREECAPACITY,FILENAME_KBYTES_FREE, oid_table_c64_kb_handler}, + { LOVFILES,FILENAME_FILES_TOTAL, oid_table_c64_kb_handler}, + { LOVFREEFILES,FILENAME_FILES_FREE, oid_table_c64_kb_handler}, + { LOVSTRIPECOUNT,"stripecount", oid_table_ulong_handler}, + { LOVSTRIPEOFFSET,"stripeoffset", oid_table_ulong_handler}, + { LOVSTRIPESIZE,"stripesize", oid_table_ulong_handler}, + { LOVSTRIPETYPE,"stripetype", oid_table_ulong_handler}, + { 0,0,0 } /*End of table*/ +}; + + +/***************************************************************************** + * Function: var_lovTable + * + ****************************************************************************/ +unsigned char * +var_lovTable(struct variable *vp, + oid *name, + size_t *length, + int exact, + size_t *var_len, + WriteMethod **write_method) +{ + return var_genericTable(vp,name,length,exact,var_len,write_method, + LOV_PATH,lov_table); +} + +struct oid_table ldlm_table[] = +{ + { LDLMNAMESPACE,0,oid_table_obj_name_handler}, + { LDLMLOCKCOUNT,"lock_count", oid_table_ulong_handler}, + { LDLMUNUSEDLOCKCOUNT,"lock_unused_count", oid_table_ulong_handler}, + { LDLMRESOURCECOUNT,"resource_count", oid_table_ulong_handler}, + { 0,0,0 } /*End of table*/ +}; + + +/***************************************************************************** + * Function: var_ldlmTable + * + ****************************************************************************/ +unsigned char * +var_ldlmTable(struct variable *vp, + oid *name, + size_t *length, + int exact, + size_t *var_len, + WriteMethod **write_method) +{ + return var_genericTable(vp,name,length,exact,var_len,write_method, + LDLM_PATH,ldlm_table); +} + + +/***************************************************************************** + * Function: write_sysStatus + * + ****************************************************************************/ +int +write_sysStatus(int action, + u_char *var_val, + u_char var_val_type, + size_t var_val_len, + u_char *statP, + oid *name, + size_t name_len) +{ + static long *long_ret; + int size; + int pid, new_value; + + + + switch ( action ) { + case RESERVE1: + if (var_val_type != ASN_INTEGER){ + fprintf(stderr, "write to sysStatus not ASN_INTEGER\n"); + return SNMP_ERR_WRONGTYPE; + } + if (var_val_len > sizeof(long_ret)){ + fprintf(stderr,"write to sysStatus: bad length\n"); + return SNMP_ERR_WRONGLENGTH; + } + if ((*var_val != ONLINE) && + (*var_val != OFFLINE) && + (*var_val != RESTART)){ + report("%s %s:line %d %s", __FILE__, __FUNCTION__, __LINE__, + "sysStatus value is invalid."); + return SNMP_ERR_WRONGVALUE; + } + break; + + + case RESERVE2: + size = var_val_len; + long_ret = (long *) var_val; + + + break; + + + case FREE: + /* Release any resources that have been allocated */ + break; + + + case ACTION: + /* The variable has been stored in long_ret for + you to use, and you have just been asked to do something with + it. Note that anything done here must be reversable in the UNDO case */ + new_value = *(int *) var_val; + switch (new_value) { + case ONLINE: + lustrefs_ctrl(ONLINE); + break; + + case OFFLINE: + lustrefs_ctrl(OFFLINE); + break; + + case RESTART: + lustrefs_ctrl(RESTART); + break; + + default: + break; + } + break; + + + case UNDO: + /* Back out any changes made in the ACTION case */ + break; + + + case COMMIT: + /* Things are working well, so it's now safe to make the change + permanently. Make sure that anything done here can't fail! */ + break; + } + return SNMP_ERR_NOERROR; +} + diff --git a/snmp/lustre-snmp.h b/snmp/lustre-snmp.h new file mode 100644 index 0000000..c4c10e0 --- /dev/null +++ b/snmp/lustre-snmp.h @@ -0,0 +1,45 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * Copyright (c) 2005 Cluster File Systems, Inc. + * Author: PJ Kirner + * + * This file is part of Lustre, http://www.lustre.org. + * + * Lustre is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * Lustre 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 Lustre; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef LUSTRE_SNMP_H +#define LUSTRE_SNMP_H + +#include "lustre-snmp-util.h" + +config_require(util_funcs) +config_add_mib(LUSTRE-MIB) +config_require(lustre/cfs_util) +config_require(lustre/cfs_trap) + +/* function prototypes */ +void init_cfsNetSNMPPlugin(void); +FindVarMethod var_clusterFileSystems; +FindVarMethod var_osdTable; +FindVarMethod var_oscTable; +FindVarMethod var_mdsTable; +FindVarMethod var_mdcTable; +FindVarMethod var_cliTable; +FindVarMethod var_ldlmTable; +FindVarMethod var_lovTable; +WriteMethod write_sysStatus; + +#endif /* LUSTRE_SNMP_H */