summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_storage_tbl.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bsnmpd/modules/snmp_hostres/hostres_storage_tbl.c')
-rw-r--r--usr.sbin/bsnmpd/modules/snmp_hostres/hostres_storage_tbl.c668
1 files changed, 0 insertions, 668 deletions
diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_storage_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_storage_tbl.c
deleted file mode 100644
index 488d9f5..0000000
--- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_storage_tbl.c
+++ /dev/null
@@ -1,668 +0,0 @@
-/*-
- * Copyright (c) 2005-2006 The FreeBSD Project
- * All rights reserved.
- *
- * Author: Victor Cruceru <soc-victor@freebsd.org>
- *
- * Redistribution of this software and documentation and use in source and
- * binary forms, with or without modification, are permitted provided that
- * the following conditions are met:
- *
- * 1. Redistributions of source code or documentation must retain the above
- * copyright notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-/*
- * Host Resources MIB for SNMPd. Implementation for hrStorageTable
- */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/sysctl.h>
-#include <sys/vmmeter.h>
-#include <sys/mount.h>
-
-#include <vm/vm_param.h>
-
-#include <assert.h>
-#include <err.h>
-#include <limits.h>
-#include <memstat.h>
-#include <paths.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h> /* for getpagesize() */
-#include <sysexits.h>
-
-#include "hostres_snmp.h"
-#include "hostres_oid.h"
-#include "hostres_tree.h"
-
-/* maximum length for descritpion string according to MIB */
-#define SE_DESC_MLEN (255 + 1)
-
-/*
- * This structure is used to hold a SNMP table entry
- * for HOST-RESOURCES-MIB's hrStorageTable
- */
-struct storage_entry {
- int32_t index;
- const struct asn_oid *type;
- u_char *descr;
- int32_t allocationUnits;
- int32_t size;
- int32_t used;
- uint32_t allocationFailures;
-#define HR_STORAGE_FOUND 0x001
- uint32_t flags; /* to be used internally*/
- TAILQ_ENTRY(storage_entry) link;
-};
-TAILQ_HEAD(storage_tbl, storage_entry);
-
-/*
- * Next structure is used to keep o list of mappings from a specific name
- * (a_name) to an entry in the hrStorageTblEntry. We are trying to keep the
- * same index for a specific name at least for the duration of one SNMP agent
- * run.
- */
-struct storage_map_entry {
- int32_t hrIndex; /* used for storage_entry::index */
-
- /* map key, also used for storage_entry::descr */
- u_char *a_name;
-
- /*
- * next may be NULL if the respective storage_entry
- * is (temporally) gone
- */
- struct storage_entry *entry;
- STAILQ_ENTRY(storage_map_entry) link;
-};
-STAILQ_HEAD(storage_map, storage_map_entry);
-
-/* the head of the list with table's entries */
-static struct storage_tbl storage_tbl = TAILQ_HEAD_INITIALIZER(storage_tbl);
-
-/*for consistent table indexing*/
-static struct storage_map storage_map =
- STAILQ_HEAD_INITIALIZER(storage_map);
-
-/* last (agent) tick when hrStorageTable was updated */
-static uint64_t storage_tick;
-
-/* maximum number of ticks between two refreshs */
-uint32_t storage_tbl_refresh = HR_STORAGE_TBL_REFRESH * 100;
-
-/* for kvm_getswapinfo, malloc'd */
-static struct kvm_swap *swap_devs;
-static size_t swap_devs_len; /* item count for swap_devs */
-
-/* for getfsstat, malloc'd */
-static struct statfs *fs_buf;
-static size_t fs_buf_count; /* item count for fs_buf */
-
-static struct vmtotal mem_stats;
-
-/* next int available for indexing the hrStorageTable */
-static uint32_t next_storage_index = 1;
-
-/* start of list for memory detailed stats */
-static struct memory_type_list *mt_list;
-
-/* Constants */
-static const struct asn_oid OIDX_hrStorageRam_c = OIDX_hrStorageRam;
-static const struct asn_oid OIDX_hrStorageVirtualMemory_c =
- OIDX_hrStorageVirtualMemory;
-
-/**
- * Create a new entry into the storage table and, if neccessary, an
- * entry into the storage map.
- */
-static struct storage_entry *
-storage_entry_create(const char *name)
-{
- struct storage_entry *entry;
- struct storage_map_entry *map;
- size_t name_len;
-
- assert(name != NULL);
- assert(strlen(name) > 0);
-
- STAILQ_FOREACH(map, &storage_map, link)
- if (strcmp(map->a_name, name) == 0)
- break;
-
- if (map == NULL) {
- /* new object - get a new index */
- if (next_storage_index > INT_MAX) {
- syslog(LOG_ERR,
- "%s: hrStorageTable index wrap", __func__);
- errx(EX_SOFTWARE, "hrStorageTable index wrap");
- }
-
- if ((map = malloc(sizeof(*map))) == NULL) {
- syslog(LOG_ERR, "hrStorageTable: %s: %m", __func__ );
- return (NULL);
- }
-
- name_len = strlen(name) + 1;
- if (name_len > SE_DESC_MLEN)
- name_len = SE_DESC_MLEN;
-
- if ((map->a_name = malloc(name_len)) == NULL) {
- free(map);
- return (NULL);
- }
-
- strlcpy(map->a_name, name, name_len);
- map->hrIndex = next_storage_index++;
-
- STAILQ_INSERT_TAIL(&storage_map, map, link);
-
- HRDBG("%s added into hrStorageMap at index=%d",
- name, map->hrIndex);
- } else {
- HRDBG("%s exists in hrStorageMap index=%d\n",
- name, map->hrIndex);
- }
-
- if ((entry = malloc(sizeof(*entry))) == NULL) {
- syslog(LOG_WARNING, "%s: %m", __func__);
- return (NULL);
- }
- memset(entry, 0, sizeof(*entry));
-
- entry->index = map->hrIndex;
-
- if ((entry->descr = strdup(map->a_name)) == NULL) {
- free(entry);
- return (NULL);
- }
-
- map->entry = entry;
-
- INSERT_OBJECT_INT(entry, &storage_tbl);
-
- return (entry);
-}
-
-/**
- * Delete an entry from the storage table.
- */
-static void
-storage_entry_delete(struct storage_entry *entry)
-{
- struct storage_map_entry *map;
-
- assert(entry != NULL);
-
- TAILQ_REMOVE(&storage_tbl, entry, link);
- STAILQ_FOREACH(map, &storage_map, link)
- if (map->entry == entry) {
- map->entry = NULL;
- break;
- }
- free(entry->descr);
- free(entry);
-}
-
-/**
- * Find a table entry by its name.
- */
-static struct storage_entry *
-storage_find_by_name(const char *name)
-{
- struct storage_entry *entry;
-
- TAILQ_FOREACH(entry, &storage_tbl, link)
- if (strcmp(entry->descr, name) == 0)
- return (entry);
-
- return (NULL);
-}
-
-/*
- * VM info.
- */
-static void
-storage_OS_get_vm(void)
-{
- int mib[2] = { CTL_VM, VM_TOTAL };
- size_t len = sizeof(mem_stats);
- int page_size_bytes;
- struct storage_entry *entry;
-
- if (sysctl(mib, 2, &mem_stats, &len, NULL, 0) < 0) {
- syslog(LOG_ERR,
- "hrStoragetable: %s: sysctl({CTL_VM, VM_METER}) "
- "failed: %m", __func__);
- assert(0);
- return;
- }
-
- page_size_bytes = getpagesize();
-
- /* Real Memory Metrics */
- if ((entry = storage_find_by_name("Real Memory Metrics")) == NULL &&
- (entry = storage_entry_create("Real Memory Metrics")) == NULL)
- return; /* I'm out of luck now, maybe next time */
-
- entry->flags |= HR_STORAGE_FOUND;
- entry->type = &OIDX_hrStorageRam_c;
- entry->allocationUnits = page_size_bytes;
- entry->size = mem_stats.t_rm;
- entry->used = mem_stats.t_arm; /* ACTIVE is not USED - FIXME */
- entry->allocationFailures = 0;
-
- /* Shared Real Memory Metrics */
- if ((entry = storage_find_by_name("Shared Real Memory Metrics")) ==
- NULL &&
- (entry = storage_entry_create("Shared Real Memory Metrics")) ==
- NULL)
- return;
-
- entry->flags |= HR_STORAGE_FOUND;
- entry->type = &OIDX_hrStorageRam_c;
- entry->allocationUnits = page_size_bytes;
- entry->size = mem_stats.t_rmshr;
- /* ACTIVE is not USED - FIXME */
- entry->used = mem_stats.t_armshr;
- entry->allocationFailures = 0;
-}
-
-static void
-storage_OS_get_memstat(void)
-{
- struct memory_type *mt_item;
- struct storage_entry *entry;
-
- if (mt_list == NULL) {
- if ((mt_list = memstat_mtl_alloc()) == NULL)
- /* again? we have a serious problem */
- return;
- }
-
- if (memstat_sysctl_all(mt_list, 0) < 0) {
- syslog(LOG_ERR, "memstat_sysctl_all failed: %s",
- memstat_strerror(memstat_mtl_geterror(mt_list)) );
- return;
- }
-
- if ((mt_item = memstat_mtl_first(mt_list)) == NULL) {
- /* usually this is not an error, no errno for this failure*/
- HRDBG("memstat_mtl_first failed");
- return;
- }
-
- do {
- const char *memstat_name;
- uint64_t tmp_size;
- int allocator;
- char alloc_descr[SE_DESC_MLEN];
-
- memstat_name = memstat_get_name(mt_item);
-
- if (memstat_name == NULL || strlen(memstat_name) == 0)
- continue;
-
- switch (allocator = memstat_get_allocator(mt_item)) {
-
- case ALLOCATOR_MALLOC:
- snprintf(alloc_descr, sizeof(alloc_descr),
- "MALLOC: %s", memstat_name);
- break;
-
- case ALLOCATOR_UMA:
- snprintf(alloc_descr, sizeof(alloc_descr),
- "UMA: %s", memstat_name);
- break;
-
- default:
- snprintf(alloc_descr, sizeof(alloc_descr),
- "UNKNOWN%d: %s", allocator, memstat_name);
- break;
- }
-
- if ((entry = storage_find_by_name(alloc_descr)) == NULL &&
- (entry = storage_entry_create(alloc_descr)) == NULL)
- return;
-
- entry->flags |= HR_STORAGE_FOUND;
- entry->type = &OIDX_hrStorageRam_c;
-
- if ((tmp_size = memstat_get_size(mt_item)) == 0)
- tmp_size = memstat_get_sizemask(mt_item);
- entry->allocationUnits =
- (tmp_size > INT_MAX ? INT_MAX : (int32_t)tmp_size);
-
- tmp_size = memstat_get_countlimit(mt_item);
- entry->size =
- (tmp_size > INT_MAX ? INT_MAX : (int32_t)tmp_size);
-
- tmp_size = memstat_get_count(mt_item);
- entry->used =
- (tmp_size > INT_MAX ? INT_MAX : (int32_t)tmp_size);
-
- tmp_size = memstat_get_failures(mt_item);
- entry->allocationFailures =
- (tmp_size > INT_MAX ? INT_MAX : (int32_t)tmp_size);
-
- } while((mt_item = memstat_mtl_next(mt_item)) != NULL);
-}
-
-/**
- * Get swap info
- */
-static void
-storage_OS_get_swap(void)
-{
- int nswapdev = 0;
- size_t len = sizeof(nswapdev);
- struct storage_entry *entry;
- char swap_w_prefix[SE_DESC_MLEN];
-
- if (sysctlbyname("vm.nswapdev", &nswapdev, &len, NULL,0 ) < 0) {
- syslog(LOG_ERR,
- "hrStorageTable: sysctlbyname(\"vm.nswapdev\") "
- "failed. %m");
- assert(0);
- return;
- }
-
- if (nswapdev <= 0) {
- HRDBG("vm.nswapdev is %d", nswapdev);
- return;
- }
-
- if (nswapdev + 1 != (int)swap_devs_len || swap_devs == NULL) {
- swap_devs_len = nswapdev + 1;
- swap_devs = reallocf(swap_devs,
- swap_devs_len * sizeof(struct kvm_swap));
-
- assert(swap_devs != NULL);
- if (swap_devs == NULL) {
- swap_devs_len = 0;
- return;
- }
- }
-
- nswapdev = kvm_getswapinfo(hr_kd, swap_devs, swap_devs_len, 0);
- if (nswapdev < 0) {
- syslog(LOG_ERR,
- "hrStorageTable: kvm_getswapinfo failed. %m\n");
- assert(0);
- return;
- }
-
- for (len = 0; len < (size_t)nswapdev; len++) {
- memset(&swap_w_prefix[0], '\0', sizeof(swap_w_prefix));
- snprintf(swap_w_prefix, sizeof(swap_w_prefix) - 1,
- "Swap:%s%s", _PATH_DEV, swap_devs[len].ksw_devname);
-
- entry = storage_find_by_name(swap_w_prefix);
- if (entry == NULL)
- entry = storage_entry_create(swap_w_prefix);
-
- assert (entry != NULL);
- if (entry == NULL)
- return; /* Out of luck */
-
- entry->flags |= HR_STORAGE_FOUND;
- entry->type = &OIDX_hrStorageVirtualMemory_c;
- entry->allocationUnits = getpagesize();
- entry->size = swap_devs[len].ksw_total;
- entry->used = swap_devs[len].ksw_used;
- entry->allocationFailures = 0;
- }
-}
-
-/**
- * Query the underlaying OS for the mounted file systems
- * anf fill in the respective lists (for hrStorageTable and for hrFSTable)
- */
-static void
-storage_OS_get_fs(void)
-{
- struct storage_entry *entry;
- uint64_t used_blocks_count = 0;
- char fs_string[SE_DESC_MLEN];
- int mounted_fs_count;
- int i = 0;
-
- if ((mounted_fs_count = getfsstat(NULL, 0, MNT_NOWAIT)) < 0) {
- syslog(LOG_ERR, "hrStorageTable: getfsstat() failed: %m");
- return; /* out of luck this time */
- }
-
- if (mounted_fs_count != (int)fs_buf_count || fs_buf == NULL) {
- fs_buf_count = mounted_fs_count;
- fs_buf = reallocf(fs_buf, fs_buf_count * sizeof(struct statfs));
- if (fs_buf == NULL) {
- fs_buf_count = 0;
- assert(0);
- return;
- }
- }
-
- if ((mounted_fs_count = getfsstat(fs_buf,
- fs_buf_count * sizeof(struct statfs), MNT_NOWAIT)) < 0) {
- syslog(LOG_ERR, "hrStorageTable: getfsstat() failed: %m");
- return; /* out of luck this time */
- }
-
- HRDBG("got %d mounted FS", mounted_fs_count);
-
- fs_tbl_pre_refresh();
-
- for (i = 0; i < mounted_fs_count; i++) {
- snprintf(fs_string, sizeof(fs_string),
- "%s, type: %s, dev: %s", fs_buf[i].f_mntonname,
- fs_buf[i].f_fstypename, fs_buf[i].f_mntfromname);
-
- entry = storage_find_by_name(fs_string);
- if (entry == NULL)
- entry = storage_entry_create(fs_string);
-
- assert (entry != NULL);
- if (entry == NULL)
- return; /* Out of luck */
-
- entry->flags |= HR_STORAGE_FOUND;
- entry->type = fs_get_type(&fs_buf[i]); /*XXX - This is wrong*/
-
- if (fs_buf[i].f_bsize > INT_MAX)
- entry->allocationUnits = INT_MAX;
- else
- entry->allocationUnits = fs_buf[i].f_bsize;
-
- if (fs_buf[i].f_blocks > INT_MAX)
- entry->size = INT_MAX;
- else
- entry->size = fs_buf[i].f_blocks;
-
- used_blocks_count = fs_buf[i].f_blocks - fs_buf[i].f_bfree;
-
- if (used_blocks_count > INT_MAX)
- entry->used = INT_MAX;
- else
- entry->used = used_blocks_count;
-
- entry->allocationFailures = 0;
-
- /* take care of hrFSTable */
- fs_tbl_process_statfs_entry(&fs_buf[i], entry->index);
- }
-
- fs_tbl_post_refresh();
-}
-
-/**
- * Initialize storage table and populate it.
- */
-void
-init_storage_tbl(void)
-{
- if ((mt_list = memstat_mtl_alloc()) == NULL)
- syslog(LOG_ERR,
- "hrStorageTable: memstat_mtl_alloc() failed: %m");
-
- refresh_storage_tbl(1);
-}
-
-void
-fini_storage_tbl(void)
-{
- struct storage_map_entry *n1;
-
- if (swap_devs != NULL) {
- free(swap_devs);
- swap_devs = NULL;
- }
- swap_devs_len = 0;
-
- if (fs_buf != NULL) {
- free(fs_buf);
- fs_buf = NULL;
- }
- fs_buf_count = 0;
-
- while ((n1 = STAILQ_FIRST(&storage_map)) != NULL) {
- STAILQ_REMOVE_HEAD(&storage_map, link);
- if (n1->entry != NULL) {
- TAILQ_REMOVE(&storage_tbl, n1->entry, link);
- free(n1->entry->descr);
- free(n1->entry);
- }
- free(n1->a_name);
- free(n1);
- }
- assert(TAILQ_EMPTY(&storage_tbl));
-}
-
-void
-refresh_storage_tbl(int force)
-{
- struct storage_entry *entry, *entry_tmp;
-
- if (!force && storage_tick != 0 &&
- this_tick - storage_tick < storage_tbl_refresh) {
- HRDBG("no refresh needed");
- return;
- }
-
- /* mark each entry as missing */
- TAILQ_FOREACH(entry, &storage_tbl, link)
- entry->flags &= ~HR_STORAGE_FOUND;
-
- storage_OS_get_vm();
- storage_OS_get_swap();
- storage_OS_get_fs();
- storage_OS_get_memstat();
-
- /*
- * Purge items that disappeared
- */
- TAILQ_FOREACH_SAFE(entry, &storage_tbl, link, entry_tmp)
- if (!(entry->flags & HR_STORAGE_FOUND))
- storage_entry_delete(entry);
-
- storage_tick = this_tick;
-
- HRDBG("refresh DONE");
-}
-
-/*
- * This is the implementation for a generated (by our SNMP tool)
- * function prototype, see hostres_tree.h
- * It handles the SNMP operations for hrStorageTable
- */
-int
-op_hrStorageTable(struct snmp_context *ctx __unused, struct snmp_value *value,
- u_int sub, u_int iidx __unused, enum snmp_op curr_op)
-{
- struct storage_entry *entry;
-
- refresh_storage_tbl(0);
-
- switch (curr_op) {
-
- case SNMP_OP_GETNEXT:
- if ((entry = NEXT_OBJECT_INT(&storage_tbl,
- &value->var, sub)) == NULL)
- return (SNMP_ERR_NOSUCHNAME);
-
- value->var.len = sub + 1;
- value->var.subs[sub] = entry->index;
- goto get;
-
- case SNMP_OP_GET:
- if ((entry = FIND_OBJECT_INT(&storage_tbl,
- &value->var, sub)) == NULL)
- return (SNMP_ERR_NOSUCHNAME);
- goto get;
-
- case SNMP_OP_SET:
- if ((entry = FIND_OBJECT_INT(&storage_tbl,
- &value->var, sub)) == NULL)
- return (SNMP_ERR_NO_CREATION);
- return (SNMP_ERR_NOT_WRITEABLE);
-
- case SNMP_OP_ROLLBACK:
- case SNMP_OP_COMMIT:
- abort();
- }
- abort();
-
- get:
- switch (value->var.subs[sub - 1]) {
-
- case LEAF_hrStorageIndex:
- value->v.integer = entry->index;
- return (SNMP_ERR_NOERROR);
-
- case LEAF_hrStorageType:
- assert(entry->type != NULL);
- value->v.oid = *entry->type;
- return (SNMP_ERR_NOERROR);
-
- case LEAF_hrStorageDescr:
- assert(entry->descr != NULL);
- return (string_get(value, entry->descr, -1));
- break;
-
- case LEAF_hrStorageAllocationUnits:
- value->v.integer = entry->allocationUnits;
- return (SNMP_ERR_NOERROR);
-
- case LEAF_hrStorageSize:
- value->v.integer = entry->size;
- return (SNMP_ERR_NOERROR);
-
- case LEAF_hrStorageUsed:
- value->v.integer = entry->used;
- return (SNMP_ERR_NOERROR);
-
- case LEAF_hrStorageAllocationFailures:
- value->v.uint32 = entry->allocationFailures;
- return (SNMP_ERR_NOERROR);
- }
- abort();
-}
OpenPOWER on IntegriCloud