diff options
author | Hideki Yamane <henrich@debian.org> | 2014-03-30 19:38:48 +0900 |
---|---|---|
committer | Hideki Yamane <henrich@debian.org> | 2014-03-30 19:38:48 +0900 |
commit | 7769a9595c3da9a35f31b42451b1f6c3ed4004fa (patch) | |
tree | 009bf8fd68af6bb1129e07dd8c1ed205010d81f8 /agent/mibgroup/host/hrh_storage.c | |
parent | 2e7891b0311204e0ecd5dc4a4334df01f3a6a1b4 (diff) | |
download | pkg-net-snmp-7769a9595c3da9a35f31b42451b1f6c3ed4004fa.tar.gz |
Imported Upstream version 5.7.2~dfsg
Diffstat (limited to 'agent/mibgroup/host/hrh_storage.c')
-rw-r--r-- | agent/mibgroup/host/hrh_storage.c | 520 |
1 files changed, 520 insertions, 0 deletions
diff --git a/agent/mibgroup/host/hrh_storage.c b/agent/mibgroup/host/hrh_storage.c new file mode 100644 index 0000000..ca2f854 --- /dev/null +++ b/agent/mibgroup/host/hrh_storage.c @@ -0,0 +1,520 @@ +/* + * Host Resources MIB - storage group implementation - hrh_storage.c + * + */ + +#include <net-snmp/net-snmp-config.h> +#include <net-snmp/net-snmp-includes.h> +#include <net-snmp/agent/net-snmp-agent-includes.h> +#include <net-snmp/agent/hardware/memory.h> +#include <net-snmp/agent/hardware/fsys.h> +#include "host_res.h" +#include "hrh_filesys.h" +#include "hrh_storage.h" +#include "hr_disk.h" +#include <net-snmp/utilities.h> + + +#include <sys/types.h> +#if HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif +#if HAVE_UNISTD_H +#include <unistd.h> +#endif +#if TIME_WITH_SYS_TIME +# ifdef WIN32 +# include <windows.h> +# include <errno.h> +# include <sys/timeb.h> +# else +# include <sys/time.h> +# endif +# include <time.h> +#else +# if HAVE_SYS_TIME_H +# include <sys/time.h> +# else +# include <time.h> +# endif +#endif + +#if HAVE_FCNTL_H +#include <fcntl.h> +#endif + +#if HAVE_STRING_H +#include <string.h> +#else +#include <strings.h> +#endif + +#include <net-snmp/output_api.h> + +#include <net-snmp/agent/agent_read_config.h> +#include <net-snmp/library/read_config.h> + +#define HRSTORE_MONOTONICALLY_INCREASING + + /********************* + * + * Kernel & interface information, + * and internal forward declarations + * + *********************/ + + +extern netsnmp_fsys_info *HRFS_entry; + +static void parse_storage_config(const char *, char *); + + /********************* + * + * Initialisation & common implementation functions + * + *********************/ +int Get_Next_HR_Store(void); +void Init_HR_Store(void); +int header_hrstore(struct variable *, oid *, size_t *, int, + size_t *, WriteMethod **); +void* header_hrstoreEntry(struct variable *, oid *, size_t *, + int, size_t *, WriteMethod **); +Netsnmp_Node_Handler handle_memsize; + + +#define HRSTORE_MEMSIZE 1 +#define HRSTORE_INDEX 2 +#define HRSTORE_TYPE 3 +#define HRSTORE_DESCR 4 +#define HRSTORE_UNITS 5 +#define HRSTORE_SIZE 6 +#define HRSTORE_USED 7 +#define HRSTORE_FAILS 8 + +struct variable2 hrstore_variables[] = { + {HRSTORE_INDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY, + var_hrstore, 1, {1}}, + {HRSTORE_TYPE, ASN_OBJECT_ID, NETSNMP_OLDAPI_RONLY, + var_hrstore, 1, {2}}, + {HRSTORE_DESCR, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY, + var_hrstore, 1, {3}}, + {HRSTORE_UNITS, ASN_INTEGER, NETSNMP_OLDAPI_RONLY, + var_hrstore, 1, {4}}, + {HRSTORE_SIZE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY, + var_hrstore, 1, {5}}, + {HRSTORE_USED, ASN_INTEGER, NETSNMP_OLDAPI_RONLY, + var_hrstore, 1, {6}}, + {HRSTORE_FAILS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY, + var_hrstore, 1, {7}} +}; +oid hrstore_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 2 }; +oid hrMemorySize_oid[] = { 1, 3, 6, 1, 2, 1, 25, 2, 2 }; +oid hrStorageTable_oid[] = { 1, 3, 6, 1, 2, 1, 25, 2, 3, 1 }; + + +void +init_hrh_storage(void) +{ + char *appname; + + netsnmp_register_scalar( + netsnmp_create_handler_registration("host/hrMemorySize", handle_memsize, + hrMemorySize_oid, OID_LENGTH(hrMemorySize_oid), + HANDLER_CAN_RONLY)); + REGISTER_MIB("host/hr_storage", hrstore_variables, variable2, + hrStorageTable_oid); + + appname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, + NETSNMP_DS_LIB_APPTYPE); + netsnmp_ds_register_config(ASN_BOOLEAN, appname, "skipNFSInHostResources", + NETSNMP_DS_APPLICATION_ID, + NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES); + + netsnmp_ds_register_config(ASN_BOOLEAN, appname, "realStorageUnits", + NETSNMP_DS_APPLICATION_ID, + NETSNMP_DS_AGENT_REALSTORAGEUNITS); + + snmpd_register_config_handler("storageUseNFS", parse_storage_config, NULL, + "1 | 2\t\t(1 = enable, 2 = disable)"); +} + +static int storageUseNFS = 1; /* Default to reporting NFS mounts as NetworkDisk */ + +static void +parse_storage_config(const char *token, char *cptr) +{ + char *val; + int ival; + char *st; + + val = strtok_r(cptr, " \t", &st); + if (!val) { + config_perror("Missing FLAG parameter in storageUseNFS"); + return; + } + ival = atoi(val); + if (ival < 1 || ival > 2) { + config_perror("storageUseNFS must be 1 or 2"); + return; + } + storageUseNFS = (ival == 1) ? 1 : 0; +} + +/* + * header_hrstoreEntry(... + * Arguments: + * vp IN - pointer to variable entry that points here + * name IN/OUT - IN/name requested, OUT/name found + * length IN/OUT - length of IN/OUT oid's + * exact IN - TRUE if an exact match was requested + * var_len OUT - length of variable or 0 if function returned + * write_method + * + */ + +void * +header_hrstoreEntry(struct variable *vp, + oid * name, + size_t * length, + int exact, + size_t * var_len, WriteMethod ** write_method) +{ +#define HRSTORE_ENTRY_NAME_LENGTH 11 + oid newname[MAX_OID_LEN]; + int storage_idx, LowIndex = -1; + int result; + int idx = -1; + netsnmp_memory_info *mem = NULL; + + DEBUGMSGTL(("host/hr_storage", "var_hrstoreEntry: request ")); + DEBUGMSGOID(("host/hr_storage", name, *length)); + DEBUGMSG(("host/hr_storage", " exact=%d\n", exact)); + + memcpy((char *) newname, (char *) vp->name, + (int) vp->namelen * sizeof(oid)); + result = snmp_oid_compare(name, *length, vp->name, vp->namelen); + + DEBUGMSGTL(("host/hr_storage", "var_hrstoreEntry: compare ")); + DEBUGMSGOID(("host/hr_storage", vp->name, vp->namelen)); + DEBUGMSG(("host/hr_storage", " => %d\n", result)); + + + if (result < 0 || + *length <= HRSTORE_ENTRY_NAME_LENGTH ) { + /* + * Requested OID too early or too short to refer + * to a valid row (for the current column object). + * GET requests should fail, GETNEXT requests + * should use the first row. + */ + if ( exact ) + return NULL; + netsnmp_memory_load(); + mem = netsnmp_memory_get_first( 0 ); + } + else { + /* + * Otherwise, retrieve the requested + * (or following) row as appropriate. + */ + if ( exact && *length > HRSTORE_ENTRY_NAME_LENGTH+1 ) + return NULL; /* Too long for a valid instance */ + idx = name[ HRSTORE_ENTRY_NAME_LENGTH ]; + if ( idx < NETSNMP_MEM_TYPE_MAX ) { + netsnmp_memory_load(); + mem = ( exact ? netsnmp_memory_get_byIdx( idx, 0 ) : + netsnmp_memory_get_next_byIdx( idx, 0 )); + } + } + + /* + * If this matched a memory-based entry, then + * update the OID parameter(s) for GETNEXT requests. + */ + if ( mem ) { + if ( !exact ) { + newname[ HRSTORE_ENTRY_NAME_LENGTH ] = mem->idx; + memcpy((char *) name, (char *) newname, + ((int) vp->namelen + 1) * sizeof(oid)); + *length = vp->namelen + 1; + } + } + /* + * If this didn't match a memory-based entry, + * then consider the disk-based storage. + */ + else { + Init_HR_Store(); + for (;;) { + storage_idx = Get_Next_HR_Store(); + DEBUGMSG(("host/hr_storage", "(index %d ....", storage_idx)); + if (storage_idx == -1) + break; + newname[HRSTORE_ENTRY_NAME_LENGTH] = storage_idx; + DEBUGMSGOID(("host/hr_storage", newname, *length)); + DEBUGMSG(("host/hr_storage", "\n")); + result = snmp_oid_compare(name, *length, newname, vp->namelen + 1); + if (exact && (result == 0)) { + LowIndex = storage_idx; + /* + * Save storage status information + */ + break; + } + if ((!exact && (result < 0)) && + (LowIndex == -1 || storage_idx < LowIndex)) { + LowIndex = storage_idx; + /* + * Save storage status information + */ +#ifdef HRSTORE_MONOTONICALLY_INCREASING + break; +#endif + } + } + if ( LowIndex != -1 ) { + if ( !exact ) { + newname[ HRSTORE_ENTRY_NAME_LENGTH ] = LowIndex; + memcpy((char *) name, (char *) newname, + ((int) vp->namelen + 1) * sizeof(oid)); + *length = vp->namelen + 1; + } + mem = (netsnmp_memory_info*)0xffffffff; /* To indicate 'success' */ + } + } + + *write_method = (WriteMethod*)0; + *var_len = sizeof(long); /* default to 'long' results */ + + /* + * ... and return the appropriate row + */ + DEBUGMSGTL(("host/hr_storage", "var_hrstoreEntry: process ")); + DEBUGMSGOID(("host/hr_storage", name, *length)); + DEBUGMSG(("host/hr_storage", " (%p)\n", mem)); + return (void*)mem; +} + +oid storage_type_id[] = { 1, 3, 6, 1, 2, 1, 25, 2, 1, 1 }; /* hrStorageOther */ +int storage_type_len = + sizeof(storage_type_id) / sizeof(storage_type_id[0]); + + /********************* + * + * System specific implementation functions + * + *********************/ + +int +handle_memsize(netsnmp_mib_handler *handler, + netsnmp_handler_registration *reginfo, + netsnmp_agent_request_info *reqinfo, + netsnmp_request_info *requests) +{ + netsnmp_memory_info *mem_info; + int val; + + /* + * We just need to handle valid GET requests, as invalid instances + * are rejected automatically, and (valid) GETNEXT requests are + * converted into the appropriate GET request. + * + * We also only ever receive one request at a time. + */ + switch (reqinfo->mode) { + case MODE_GET: + netsnmp_memory_load(); + mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 0 ); + if ( !mem_info || mem_info->size == -1 || mem_info->units == -1 ) + netsnmp_set_request_error( reqinfo, requests, SNMP_NOSUCHOBJECT ); + else { + val = mem_info->size; /* memtotal */ + val *= (mem_info->units/1024); + snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER, + (u_char *)&val, sizeof(val)); + } + return SNMP_ERR_NOERROR; + + default: + /* + * we should never get here, so this is a really bad error + */ + snmp_log(LOG_ERR, "unknown mode (%d) in handle_memsize\n", + reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} + + +u_char * +var_hrstore(struct variable *vp, + oid * name, + size_t * length, + int exact, size_t * var_len, WriteMethod ** write_method) +{ + int store_idx = 0; + static char string[1024]; + void *ptr; + netsnmp_memory_info *mem = NULL; + +really_try_next: + ptr = header_hrstoreEntry(vp, name, length, exact, var_len, + write_method); + if (ptr == NULL) + return NULL; + + store_idx = name[ HRSTORE_ENTRY_NAME_LENGTH ]; + if (HRFS_entry && + store_idx > NETSNMP_MEM_TYPE_MAX && + netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, + NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES) && + Check_HR_FileSys_NFS()) + return NULL; + if (store_idx <= NETSNMP_MEM_TYPE_MAX ) { + mem = (netsnmp_memory_info*)ptr; + } + + + + switch (vp->magic) { + case HRSTORE_INDEX: + long_return = store_idx; + return (u_char *) & long_return; + case HRSTORE_TYPE: + if (store_idx > NETSNMP_MEM_TYPE_MAX) + if (HRFS_entry->flags & NETSNMP_FS_FLAG_REMOTE ) + storage_type_id[storage_type_len - 1] = 10; /* Network Disk */ + else if (HRFS_entry->flags & NETSNMP_FS_FLAG_REMOVE ) + storage_type_id[storage_type_len - 1] = 5; /* Removable Disk */ + else + storage_type_id[storage_type_len - 1] = 4; /* Assume fixed */ + else + switch (store_idx) { + case NETSNMP_MEM_TYPE_PHYSMEM: + case NETSNMP_MEM_TYPE_USERMEM: + storage_type_id[storage_type_len - 1] = 2; /* RAM */ + break; + case NETSNMP_MEM_TYPE_VIRTMEM: + case NETSNMP_MEM_TYPE_SWAP: + storage_type_id[storage_type_len - 1] = 3; /* Virtual Mem */ + break; + default: + storage_type_id[storage_type_len - 1] = 1; /* Other */ + break; + } + *var_len = sizeof(storage_type_id); + return (u_char *) storage_type_id; + case HRSTORE_DESCR: + if (store_idx > NETSNMP_MEM_TYPE_MAX) { + strlcpy(string, HRFS_entry->path, sizeof(string)); + *var_len = strlen(string); + return (u_char *) string; + } else { + if ( !mem || !mem->descr ) + goto try_next; + *var_len = strlen(mem->descr); + return (u_char *) mem->descr; + } + case HRSTORE_UNITS: + if (store_idx > NETSNMP_MEM_TYPE_MAX) { + if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, + NETSNMP_DS_AGENT_REALSTORAGEUNITS)) + long_return = HRFS_entry->units & 0xffffffff; + else + long_return = HRFS_entry->units_32; + } else { + if ( !mem || mem->units == -1 ) + goto try_next; + long_return = mem->units; + } + return (u_char *) & long_return; + case HRSTORE_SIZE: + if (store_idx > NETSNMP_MEM_TYPE_MAX) { + if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, + NETSNMP_DS_AGENT_REALSTORAGEUNITS)) + long_return = HRFS_entry->size & 0xffffffff; + else + long_return = HRFS_entry->size_32; + } else { + if ( !mem || mem->size == -1 ) + goto try_next; + long_return = mem->size; + } + return (u_char *) & long_return; + case HRSTORE_USED: + if (store_idx > NETSNMP_MEM_TYPE_MAX) { + if (netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, + NETSNMP_DS_AGENT_REALSTORAGEUNITS)) + long_return = HRFS_entry->used & 0xffffffff; + else + long_return = HRFS_entry->used_32; + } else { + if ( !mem || mem->size == -1 || mem->free == -1 ) + goto try_next; + long_return = mem->size - mem->free; + } + return (u_char *) & long_return; + case HRSTORE_FAILS: + if (store_idx > NETSNMP_MEM_TYPE_MAX) +#if NETSNMP_NO_DUMMY_VALUES + goto try_next; +#else + long_return = 0; +#endif + else { + if ( !mem || mem->other == -1 ) + goto try_next; + long_return = mem->other; + } + return (u_char *) & long_return; + default: + DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrstore\n", + vp->magic)); + } + return NULL; + + try_next: + if (!exact) + goto really_try_next; + + return NULL; +} + + + /********************* + * + * Internal implementation functions + * + *********************/ + +static int HRS_index; + +void +Init_HR_Store(void) +{ + HRS_index = 0; + Init_HR_FileSys(); +} + +int +Get_Next_HR_Store(void) +{ + /* + * File-based storage + */ + for (;;) { + HRS_index = Get_Next_HR_FileSys(); + if (HRS_index >= 0) { + if (!(netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, + NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES) && + Check_HR_FileSys_NFS())) { + return HRS_index + NETSNMP_MEM_TYPE_MAX; + } + } else { + return -1; + } + } +} + |