Blame agent/mibgroup/host/hr_storage.c

Packit fcad23
/*
Packit fcad23
 *  Host Resources MIB - storage group implementation - hr_storage.c
Packit fcad23
 *
Packit fcad23
 */
Packit fcad23
Packit fcad23
#include <net-snmp/net-snmp-config.h>
Packit fcad23
Packit fcad23
#if defined(freebsd5)
Packit fcad23
/* undefine these in order to use getfsstat */
Packit fcad23
#undef HAVE_STATVFS
Packit fcad23
#undef HAVE_STRUCT_STATVFS_F_FRSIZE
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#include <sys/types.h>
Packit fcad23
#if HAVE_SYS_PARAM_H
Packit fcad23
#include <sys/param.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_UNISTD_H
Packit fcad23
#include <unistd.h>
Packit fcad23
#endif
Packit fcad23
#if TIME_WITH_SYS_TIME
Packit fcad23
# include <sys/time.h>
Packit fcad23
# include <time.h>
Packit fcad23
#else
Packit fcad23
# if HAVE_SYS_TIME_H
Packit fcad23
#  include <sys/time.h>
Packit fcad23
# else
Packit fcad23
#  include <time.h>
Packit fcad23
# endif
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#if (!defined(mingw32) && !defined(WIN32))
Packit fcad23
#if HAVE_UTMPX_H
Packit fcad23
#include <utmpx.h>
Packit fcad23
#else
Packit fcad23
#include <utmp.h>
Packit fcad23
#endif
Packit fcad23
#endif /* mingw32 */
Packit fcad23
#ifndef dynix
Packit fcad23
#if HAVE_SYS_VM_H
Packit fcad23
#include <sys/vm.h>
Packit fcad23
#if (!defined(KERNEL) || defined(MACH_USER_API)) && defined(HAVE_SYS_VMMETER_H) /*OS X does not #include <sys/vmmeter.h> if (defined(KERNEL) && !defined(MACH_USER_API)) */
Packit fcad23
#include <sys/vmmeter.h>
Packit fcad23
#endif
Packit fcad23
#else
Packit fcad23
#if HAVE_VM_VM_H
Packit fcad23
#include <vm/vm.h>
Packit fcad23
#if HAVE_MACHINE_TYPES_H
Packit fcad23
#include <machine/types.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_VMMETER_H
Packit fcad23
#include <sys/vmmeter.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_VM_VM_PARAM_H
Packit fcad23
#include <vm/vm_param.h>
Packit fcad23
#endif
Packit fcad23
#else
Packit fcad23
#if HAVE_SYS_VMPARAM_H
Packit fcad23
#include <sys/vmparam.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_VMMAC_H
Packit fcad23
#include <sys/vmmac.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_VMMETER_H
Packit fcad23
#include <sys/vmmeter.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_VMSYSTM_H
Packit fcad23
#include <sys/vmsystm.h>
Packit fcad23
#endif
Packit fcad23
#endif                          /* vm/vm.h */
Packit fcad23
#endif                          /* sys/vm.h */
Packit fcad23
#if defined(HAVE_UVM_UVM_PARAM_H) && defined(HAVE_UVM_UVM_EXTERN_H)
Packit fcad23
#include <uvm/uvm_param.h>
Packit fcad23
#include <uvm/uvm_extern.h>
Packit fcad23
#elif defined(HAVE_VM_VM_PARAM_H) && defined(HAVE_VM_VM_EXTERN_H)
Packit fcad23
#include <vm/vm_param.h>
Packit fcad23
#include <vm/vm_extern.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_KVM_H
Packit fcad23
#include <kvm.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_FCNTL_H
Packit fcad23
#include <fcntl.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_POOL_H
Packit fcad23
#if defined(MBPOOL_SYMBOL) && defined(MCLPOOL_SYMBOL)
Packit fcad23
#define __POOL_EXPOSE
Packit fcad23
#include <sys/pool.h>
Packit fcad23
#else
Packit fcad23
#undef HAVE_SYS_POOL_H
Packit fcad23
#endif
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_MBUF_H
Packit fcad23
#include <sys/mbuf.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_SYSCTL_H
Packit fcad23
#include <sys/sysctl.h>
Packit fcad23
#if defined(CTL_HW) && defined(HW_PAGESIZE)
Packit fcad23
#define USE_SYSCTL
Packit fcad23
#endif
Packit fcad23
#if USE_MACH_HOST_STATISTICS
Packit fcad23
#include <mach/mach.h>
Packit fcad23
#elif defined(CTL_VM) && (defined(VM_METER) || defined(VM_UVMEXP))
Packit fcad23
#define USE_SYSCTL_VM
Packit fcad23
#endif
Packit fcad23
#endif                          /* if HAVE_SYS_SYSCTL_H */
Packit fcad23
#endif                          /* ifndef dynix */
Packit fcad23
Packit fcad23
#if (defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)) && HAVE_LIBPERFSTAT_H
Packit fcad23
#ifdef HAVE_SYS_PROTOSW_H
Packit fcad23
#include <sys/protosw.h>
Packit fcad23
#endif
Packit fcad23
#include <libperfstat.h>
Packit fcad23
#endif
Packit fcad23
Packit fcad23
Packit fcad23
#include "host_res.h"
Packit fcad23
#include "hr_storage.h"
Packit fcad23
#include "hr_filesys.h"
Packit fcad23
#include <net-snmp/agent/auto_nlist.h>
Packit fcad23
Packit fcad23
#if HAVE_MNTENT_H
Packit fcad23
#include <mntent.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_MNTTAB_H
Packit fcad23
#include <sys/mnttab.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_STATVFS_H
Packit fcad23
#include <sys/statvfs.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_VFS_H
Packit fcad23
#include <sys/vfs.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_SYS_MOUNT_H
Packit fcad23
#ifdef __osf__
Packit fcad23
#undef m_next
Packit fcad23
#undef m_data
Packit fcad23
#endif
Packit fcad23
#include <sys/mount.h>
Packit fcad23
#endif
Packit fcad23
#ifdef HAVE_MACHINE_PARAM_H
Packit fcad23
#include <machine/param.h>
Packit fcad23
#endif
Packit fcad23
#include <sys/stat.h>
Packit fcad23
Packit fcad23
#if defined(hpux10) || defined(hpux11)
Packit fcad23
#include <sys/pstat.h>
Packit fcad23
#endif
Packit fcad23
#if defined(solaris2)
Packit fcad23
#if HAVE_SYS_SWAP_H
Packit fcad23
#include <sys/swap.h>
Packit fcad23
#endif
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#if HAVE_STRING_H
Packit fcad23
#include <string.h>
Packit fcad23
#else
Packit fcad23
#include <strings.h>
Packit fcad23
#endif
Packit fcad23
#if HAVE_NBUTIL_H
Packit fcad23
#include <nbutil.h>
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#include <net-snmp/utilities.h>
Packit fcad23
#include <net-snmp/output_api.h>
Packit fcad23
Packit fcad23
#include <net-snmp/agent/net-snmp-agent-includes.h>
Packit fcad23
#include <net-snmp/agent/hardware/memory.h>
Packit fcad23
Packit fcad23
#ifdef solaris2
Packit fcad23
#include "kernel_sunos5.h"
Packit fcad23
#endif
Packit fcad23
Packit fcad23
#include <net-snmp/agent/agent_read_config.h>
Packit fcad23
#include <net-snmp/library/read_config.h>
Packit fcad23
Packit fcad23
#define HRSTORE_MONOTONICALLY_INCREASING
Packit fcad23
Packit fcad23
        /*********************
Packit fcad23
	 *
Packit fcad23
	 *  Kernel & interface information,
Packit fcad23
	 *   and internal forward declarations
Packit fcad23
	 *
Packit fcad23
	 *********************/
Packit fcad23
Packit fcad23
Packit fcad23
#ifdef solaris2
Packit fcad23
Packit fcad23
extern struct mnttab *HRFS_entry;
Packit fcad23
#define HRFS_mount	mnt_mountp
Packit fcad23
#define HRFS_statfs	statvfs
Packit fcad23
#define HRFS_HAS_FRSIZE HAVE_STRUCT_STATVFS_F_FRSIZE
Packit fcad23
Packit fcad23
#elif defined(WIN32)
Packit fcad23
/* fake block size */
Packit fcad23
#define FAKED_BLOCK_SIZE 512
Packit fcad23
Packit fcad23
extern struct win_statfs *HRFS_entry;
Packit fcad23
#define HRFS_statfs	win_statfs
Packit fcad23
#define HRFS_mount	f_driveletter
Packit fcad23
Packit fcad23
#elif defined(HAVE_STATVFS) && defined(__NetBSD__)
Packit fcad23
Packit fcad23
extern struct statvfs *HRFS_entry;
Packit fcad23
extern int      fscount;
Packit fcad23
#define HRFS_statfs	statvfs
Packit fcad23
#define HRFS_mount	f_mntonname
Packit fcad23
#define HRFS_HAS_FRSIZE HAVE_STRUCT_STATVFS_F_FRSIZE
Packit fcad23
Packit fcad23
#elif defined(HAVE_STATVFS)  && defined(HAVE_STRUCT_STATVFS_MNT_DIR)
Packit fcad23
Packit fcad23
extern struct mntent *HRFS_entry;
Packit fcad23
extern int      fscount;
Packit fcad23
#define HRFS_statfs	statvfs
Packit fcad23
#define HRFS_mount	mnt_dir
Packit fcad23
#define HRFS_HAS_FRSIZE HAVE_STRUCT_STATVFS_F_FRSIZE
Packit fcad23
Packit fcad23
#elif defined(HAVE_GETFSSTAT) && !defined(HAVE_STATFS) && defined(HAVE_STATVFS)
Packit fcad23
Packit fcad23
extern struct statfs *HRFS_entry;
Packit fcad23
extern int      fscount;
Packit fcad23
#define HRFS_statfs	statvfs
Packit fcad23
#define HRFS_mount	f_mntonname
Packit fcad23
#define HRFS_HAS_FRSIZE STRUCT_STATVFS_HAS_F_FRSIZE
Packit fcad23
Packit fcad23
#elif defined(HAVE_GETFSSTAT)
Packit fcad23
Packit fcad23
extern struct statfs *HRFS_entry;
Packit fcad23
extern int      fscount;
Packit fcad23
#define HRFS_statfs	statfs
Packit fcad23
#define HRFS_mount	f_mntonname
Packit fcad23
#define HRFS_HAS_FRSIZE HAVE_STRUCT_STATFS_F_FRSIZE
Packit fcad23
Packit fcad23
#else
Packit fcad23
Packit fcad23
extern struct mntent *HRFS_entry;
Packit fcad23
#define HRFS_mount	mnt_dir
Packit fcad23
#define HRFS_statfs	statfs
Packit fcad23
#define HRFS_HAS_FRSIZE HAVE_STRUCT_STATFS_F_FRSIZE
Packit fcad23
Packit fcad23
#endif
Packit fcad23
	
Packit fcad23
#if defined(USE_MACH_HOST_STATISTICS)
Packit fcad23
mach_port_t myHost;
Packit fcad23
#endif
Packit fcad23
Packit fcad23
static void parse_storage_config(const char *, char *);
Packit fcad23
Packit fcad23
        /*********************
Packit fcad23
	 *
Packit fcad23
	 *  Initialisation & common implementation functions
Packit fcad23
	 *
Packit fcad23
	 *********************/
Packit fcad23
int             Get_Next_HR_Store(void);
Packit fcad23
void            Init_HR_Store(void);
Packit fcad23
int             header_hrstore(struct variable *, oid *, size_t *, int,
Packit fcad23
                               size_t *, WriteMethod **);
Packit fcad23
void*           header_hrstoreEntry(struct variable *, oid *, size_t *,
Packit fcad23
                                    int, size_t *, WriteMethod **);
Packit fcad23
Netsnmp_Node_Handler handle_memsize;
Packit fcad23
Packit fcad23
#define	HRSTORE_MEMSIZE		1
Packit fcad23
#define	HRSTORE_INDEX		2
Packit fcad23
#define	HRSTORE_TYPE		3
Packit fcad23
#define	HRSTORE_DESCR		4
Packit fcad23
#define	HRSTORE_UNITS		5
Packit fcad23
#define	HRSTORE_SIZE		6
Packit fcad23
#define	HRSTORE_USED		7
Packit fcad23
#define	HRSTORE_FAILS		8
Packit fcad23
Packit fcad23
struct variable2 hrstore_variables[] = {
Packit fcad23
    {HRSTORE_INDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
Packit fcad23
     var_hrstore, 1, {1}},
Packit fcad23
    {HRSTORE_TYPE, ASN_OBJECT_ID, NETSNMP_OLDAPI_RONLY,
Packit fcad23
     var_hrstore, 1, {2}},
Packit fcad23
    {HRSTORE_DESCR, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
Packit fcad23
     var_hrstore, 1, {3}},
Packit fcad23
    {HRSTORE_UNITS, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
Packit fcad23
     var_hrstore, 1, {4}},
Packit fcad23
    {HRSTORE_SIZE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
Packit fcad23
     var_hrstore, 1, {5}},
Packit fcad23
    {HRSTORE_USED, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
Packit fcad23
     var_hrstore, 1, {6}},
Packit fcad23
    {HRSTORE_FAILS, ASN_COUNTER, NETSNMP_OLDAPI_RONLY,
Packit fcad23
     var_hrstore, 1, {7}}
Packit fcad23
};
Packit fcad23
oid             hrMemorySize_oid[]   = { 1, 3, 6, 1, 2, 1, 25, 2, 2 };
Packit fcad23
oid             hrStorageTable_oid[] = { 1, 3, 6, 1, 2, 1, 25, 2, 3, 1 };
Packit fcad23
Packit fcad23
Packit fcad23
void
Packit fcad23
init_hr_storage(void)
Packit fcad23
{
Packit fcad23
    char *appname;
Packit fcad23
Packit fcad23
    netsnmp_register_scalar(
Packit fcad23
        netsnmp_create_handler_registration("host/hrMemorySize", handle_memsize,
Packit fcad23
                           hrMemorySize_oid, OID_LENGTH(hrMemorySize_oid),
Packit fcad23
                                             HANDLER_CAN_RONLY));
Packit fcad23
    REGISTER_MIB("host/hr_storage", hrstore_variables, variable2,
Packit fcad23
                 hrStorageTable_oid);
Packit fcad23
Packit fcad23
    appname = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID,
Packit fcad23
                                    NETSNMP_DS_LIB_APPTYPE);
Packit fcad23
    netsnmp_ds_register_config(ASN_BOOLEAN, appname, "skipNFSInHostResources", 
Packit fcad23
			       NETSNMP_DS_APPLICATION_ID,
Packit fcad23
			       NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES);
Packit fcad23
Packit fcad23
    snmpd_register_config_handler("storageUseNFS", parse_storage_config, NULL,
Packit fcad23
	"1 | 2\t\t(1 = enable, 2 = disable)");
Packit fcad23
}
Packit fcad23
Packit fcad23
static int storageUseNFS = 1;	/* Default to reporting NFS mounts as NetworkDisk */
Packit fcad23
Packit fcad23
static void
Packit fcad23
parse_storage_config(const char *token, char *cptr)
Packit fcad23
{
Packit fcad23
    char *val;
Packit fcad23
    int ival;
Packit fcad23
    char *st;
Packit fcad23
Packit fcad23
    val = strtok_r(cptr, " \t", &st);
Packit fcad23
    if (!val) {
Packit fcad23
        config_perror("Missing FLAG parameter in storageUseNFS");
Packit fcad23
        return;
Packit fcad23
    }
Packit fcad23
    ival = atoi(val);
Packit fcad23
    if (ival < 1 || ival > 2) {
Packit fcad23
        config_perror("storageUseNFS must be 1 or 2");
Packit fcad23
        return;
Packit fcad23
    }
Packit fcad23
    storageUseNFS = (ival == 1) ? 1 : 0;
Packit fcad23
}
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * header_hrstoreEntry(...
Packit fcad23
 * Arguments:
Packit fcad23
 * vp     IN      - pointer to variable entry that points here
Packit fcad23
 * name    IN/OUT  - IN/name requested, OUT/name found
Packit fcad23
 * length  IN/OUT  - length of IN/OUT oid's 
Packit fcad23
 * exact   IN      - TRUE if an exact match was requested
Packit fcad23
 * var_len OUT     - length of variable or 0 if function returned
Packit fcad23
 * write_method
Packit fcad23
 * 
Packit fcad23
 */
Packit fcad23
Packit fcad23
void *
Packit fcad23
header_hrstoreEntry(struct variable *vp,
Packit fcad23
                    oid * name,
Packit fcad23
                    size_t * length,
Packit fcad23
                    int exact,
Packit fcad23
                    size_t * var_len, WriteMethod ** write_method)
Packit fcad23
{
Packit fcad23
#define HRSTORE_ENTRY_NAME_LENGTH	11
Packit fcad23
    oid             newname[MAX_OID_LEN];
Packit fcad23
    int             storage_idx, LowIndex = -1;
Packit fcad23
    int             result;
Packit fcad23
    int                  idx = -1;
Packit fcad23
    netsnmp_memory_info *mem  = NULL;
Packit fcad23
Packit fcad23
    DEBUGMSGTL(("host/hr_storage", "var_hrstoreEntry: request "));
Packit fcad23
    DEBUGMSGOID(("host/hr_storage", name, *length));
Packit fcad23
    DEBUGMSG(("host/hr_storage", " exact=%d\n", exact));
Packit fcad23
Packit fcad23
    memcpy((char *) newname, (char *) vp->name,
Packit fcad23
           (int) vp->namelen * sizeof(oid));
Packit fcad23
    result = snmp_oid_compare(name, *length, vp->name, vp->namelen);
Packit fcad23
Packit fcad23
    DEBUGMSGTL(("host/hr_storage", "var_hrstoreEntry: compare "));
Packit fcad23
    DEBUGMSGOID(("host/hr_storage", vp->name, vp->namelen));
Packit fcad23
    DEBUGMSG(("host/hr_storage", " => %d\n", result));
Packit fcad23
Packit fcad23
Packit fcad23
    if (result < 0 ||
Packit fcad23
        *length <= HRSTORE_ENTRY_NAME_LENGTH ) {
Packit fcad23
       /*
Packit fcad23
        * Requested OID too early or too short to refer
Packit fcad23
        *   to a valid row (for the current column object).
Packit fcad23
        * GET requests should fail, GETNEXT requests
Packit fcad23
        *   should use the first row.
Packit fcad23
        */
Packit fcad23
        if ( exact )
Packit fcad23
            return NULL;
Packit fcad23
        netsnmp_memory_load();
Packit fcad23
        mem = netsnmp_memory_get_first( 0 );
Packit fcad23
    }
Packit fcad23
    else {
Packit fcad23
        /*
Packit fcad23
         * Otherwise, retrieve the requested
Packit fcad23
         *  (or following) row as appropriate.
Packit fcad23
         */
Packit fcad23
        if ( exact && *length > HRSTORE_ENTRY_NAME_LENGTH+1 )
Packit fcad23
            return NULL;   /* Too long for a valid instance */
Packit fcad23
        idx = name[ HRSTORE_ENTRY_NAME_LENGTH ];
Packit fcad23
        if ( idx < NETSNMP_MEM_TYPE_MAX ) {
Packit fcad23
            netsnmp_memory_load();
Packit fcad23
            mem = ( exact ? netsnmp_memory_get_byIdx( idx, 0 ) :
Packit fcad23
                       netsnmp_memory_get_next_byIdx( idx, 0 ));
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * If this matched a memory-based entry, then
Packit fcad23
     *    update the OID parameter(s) for GETNEXT requests.
Packit fcad23
     */
Packit fcad23
    if ( mem ) {
Packit fcad23
        if ( !exact ) {
Packit fcad23
            newname[ HRSTORE_ENTRY_NAME_LENGTH ] = mem->idx;
Packit fcad23
            memcpy((char *) name, (char *) newname,
Packit fcad23
                   ((int) vp->namelen + 1) * sizeof(oid));
Packit fcad23
            *length = vp->namelen + 1;
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
    /*
Packit fcad23
     * If this didn't match a memory-based entry,
Packit fcad23
     *   then consider the disk-based storage.
Packit fcad23
     */
Packit fcad23
    else {
Packit fcad23
        Init_HR_Store();
Packit fcad23
        for (;;) {
Packit fcad23
            storage_idx = Get_Next_HR_Store();
Packit fcad23
            DEBUGMSG(("host/hr_storage", "(index %d ....", storage_idx));
Packit fcad23
            if (storage_idx == -1)
Packit fcad23
                break;
Packit fcad23
            newname[HRSTORE_ENTRY_NAME_LENGTH] = storage_idx;
Packit fcad23
            DEBUGMSGOID(("host/hr_storage", newname, *length));
Packit fcad23
            DEBUGMSG(("host/hr_storage", "\n"));
Packit fcad23
            result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
Packit fcad23
            if (exact && (result == 0)) {
Packit fcad23
                LowIndex = storage_idx;
Packit fcad23
                /*
Packit fcad23
                 * Save storage status information 
Packit fcad23
                 */
Packit fcad23
                break;
Packit fcad23
            }
Packit fcad23
            if ((!exact && (result < 0)) &&
Packit fcad23
                (LowIndex == -1 || storage_idx < LowIndex)) {
Packit fcad23
                LowIndex = storage_idx;
Packit fcad23
                /*
Packit fcad23
                 * Save storage status information 
Packit fcad23
                 */
Packit fcad23
#ifdef HRSTORE_MONOTONICALLY_INCREASING
Packit fcad23
                break;
Packit fcad23
#endif
Packit fcad23
            }
Packit fcad23
        }
Packit fcad23
        if ( LowIndex != -1 ) {
Packit fcad23
            if ( !exact ) {
Packit fcad23
                newname[ HRSTORE_ENTRY_NAME_LENGTH ] = LowIndex;
Packit fcad23
                memcpy((char *) name, (char *) newname,
Packit fcad23
                       ((int) vp->namelen + 1) * sizeof(oid));
Packit fcad23
                *length = vp->namelen + 1;
Packit fcad23
            }
Packit fcad23
            mem = (netsnmp_memory_info*)0xffffffff;   /* To indicate 'success' */
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
Packit fcad23
    *write_method = (WriteMethod*)0;
Packit fcad23
    *var_len = sizeof(long);    /* default to 'long' results */
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     *  ... and return the appropriate row
Packit fcad23
     */
Packit fcad23
    DEBUGMSGTL(("host/hr_storage", "var_hrstoreEntry: process "));
Packit fcad23
    DEBUGMSGOID(("host/hr_storage", name, *length));
Packit fcad23
    DEBUGMSG(("host/hr_storage", " (%p)\n", mem));
Packit fcad23
    return (void*)mem;
Packit fcad23
}
Packit fcad23
Packit fcad23
oid             storage_type_id[] = { 1, 3, 6, 1, 2, 1, 25, 2, 1, 1 };  /* hrStorageOther */
Packit fcad23
int             storage_type_len =
Packit fcad23
    sizeof(storage_type_id) / sizeof(storage_type_id[0]);
Packit fcad23
Packit fcad23
        /*********************
Packit fcad23
	 *
Packit fcad23
	 *  System specific implementation functions
Packit fcad23
	 *
Packit fcad23
	 *********************/
Packit fcad23
Packit fcad23
int
Packit fcad23
handle_memsize(netsnmp_mib_handler *handler,
Packit fcad23
                netsnmp_handler_registration *reginfo,
Packit fcad23
                netsnmp_agent_request_info *reqinfo,
Packit fcad23
                netsnmp_request_info *requests)
Packit fcad23
{
Packit fcad23
    netsnmp_memory_info *mem_info;
Packit fcad23
    int val;
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * We just need to handle valid GET requests, as invalid instances
Packit fcad23
     *   are rejected automatically, and (valid) GETNEXT requests are
Packit fcad23
     *   converted into the appropriate GET request.
Packit fcad23
     *
Packit fcad23
     * We also only ever receive one request at a time.
Packit fcad23
     */
Packit fcad23
    switch (reqinfo->mode) {
Packit fcad23
    case MODE_GET:
Packit fcad23
        netsnmp_memory_load();
Packit fcad23
        mem_info = netsnmp_memory_get_byIdx( NETSNMP_MEM_TYPE_PHYSMEM, 0 );
Packit fcad23
        if ( !mem_info || mem_info->size == -1 || mem_info->units == -1 )
Packit fcad23
            netsnmp_set_request_error( reqinfo, requests, SNMP_NOSUCHOBJECT );
Packit fcad23
	else {
Packit fcad23
            val  =  mem_info->size;     /* memtotal */
Packit fcad23
            val *= (mem_info->units/1024);
Packit fcad23
            snmp_set_var_typed_value(requests->requestvb, ASN_INTEGER,
Packit fcad23
                                     (u_char *)&val, sizeof(val));
Packit fcad23
        }
Packit fcad23
        return SNMP_ERR_NOERROR;
Packit fcad23
Packit fcad23
    default:
Packit fcad23
        /*
Packit fcad23
         * we should never get here, so this is a really bad error 
Packit fcad23
         */
Packit fcad23
        snmp_log(LOG_ERR, "unknown mode (%d) in handle_memsize\n",
Packit fcad23
                 reqinfo->mode);
Packit fcad23
        return SNMP_ERR_GENERR;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    return SNMP_ERR_NOERROR;
Packit fcad23
}
Packit fcad23
Packit fcad23
Packit fcad23
u_char         *
Packit fcad23
var_hrstore(struct variable *vp,
Packit fcad23
            oid * name,
Packit fcad23
            size_t * length,
Packit fcad23
            int exact, size_t * var_len, WriteMethod ** write_method)
Packit fcad23
{
Packit fcad23
    int             store_idx = 0;
Packit fcad23
    static char     string[1024];
Packit fcad23
    struct HRFS_statfs stat_buf;
Packit fcad23
    void                *ptr;
Packit fcad23
    netsnmp_memory_info *mem = NULL;
Packit fcad23
Packit fcad23
really_try_next:
Packit fcad23
	ptr = header_hrstoreEntry(vp, name, length, exact, var_len,
Packit fcad23
					write_method);
Packit fcad23
	if (ptr == NULL)
Packit fcad23
	    return NULL;
Packit fcad23
Packit fcad23
        store_idx = name[ HRSTORE_ENTRY_NAME_LENGTH ];
Packit fcad23
        if (store_idx > NETSNMP_MEM_TYPE_MAX ) {
Packit Service 2ecd3d
            if ( netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
Packit fcad23
                                        NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES) &&
Packit Service 2ecd3d
                 Check_HR_FileSys_NFS())
Packit fcad23
                return NULL;  /* or goto try_next; */
Packit fcad23
	    if (HRFS_statfs(HRFS_entry->HRFS_mount, &stat_buf) < 0) {
Packit fcad23
		snmp_log_perror(HRFS_entry->HRFS_mount);
Packit fcad23
		goto try_next;
Packit fcad23
	    }
Packit fcad23
	} else {
Packit fcad23
	    mem = (netsnmp_memory_info*)ptr;
Packit fcad23
        }
Packit fcad23
Packit fcad23
Packit fcad23
Packit fcad23
    switch (vp->magic) {
Packit fcad23
    case HRSTORE_INDEX:
Packit fcad23
        long_return = store_idx;
Packit fcad23
        return (u_char *) & long_return;
Packit fcad23
    case HRSTORE_TYPE:
Packit fcad23
        if (store_idx > NETSNMP_MEM_TYPE_MAX)
Packit fcad23
            if (storageUseNFS && Check_HR_FileSys_NFS())
Packit fcad23
                storage_type_id[storage_type_len - 1] = 10;     /* Network Disk */
Packit fcad23
#if HAVE_HASMNTOPT && !(defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7))
Packit fcad23
            /* 
Packit fcad23
             * hasmntopt takes "const struct mntent*", but HRFS_entry has been
Packit fcad23
             * defined differently for AIX, so skip this for AIX
Packit fcad23
             */
Packit fcad23
            else if (hasmntopt(HRFS_entry, "loop") != NULL)
Packit fcad23
                storage_type_id[storage_type_len - 1] = 5;      /* Removable Disk */
Packit fcad23
#endif
Packit fcad23
            else
Packit fcad23
                storage_type_id[storage_type_len - 1] = 4;      /* Assume fixed */
Packit fcad23
        else
Packit fcad23
            switch (store_idx) {
Packit fcad23
            case NETSNMP_MEM_TYPE_PHYSMEM:
Packit fcad23
            case NETSNMP_MEM_TYPE_USERMEM:
Packit fcad23
                storage_type_id[storage_type_len - 1] = 2;      /* RAM */
Packit fcad23
                break;
Packit fcad23
            case NETSNMP_MEM_TYPE_VIRTMEM:
Packit fcad23
            case NETSNMP_MEM_TYPE_SWAP:
Packit fcad23
                storage_type_id[storage_type_len - 1] = 3;      /* Virtual Mem */
Packit fcad23
                break;
Packit fcad23
            default:
Packit fcad23
                storage_type_id[storage_type_len - 1] = 1;      /* Other */
Packit fcad23
                break;
Packit fcad23
            }
Packit fcad23
        *var_len = sizeof(storage_type_id);
Packit fcad23
        return (u_char *) storage_type_id;
Packit fcad23
    case HRSTORE_DESCR:
Packit fcad23
        if (store_idx > NETSNMP_MEM_TYPE_MAX) {
Packit fcad23
            strlcpy(string, HRFS_entry->HRFS_mount, sizeof(string));
Packit fcad23
            *var_len = strlen(string);
Packit fcad23
            return (u_char *) string;
Packit fcad23
        } else {
Packit fcad23
            if ( !mem || !mem->descr )
Packit fcad23
                goto try_next;
Packit fcad23
            *var_len = strlen(mem->descr);
Packit fcad23
            return (u_char *) mem->descr;
Packit fcad23
        }
Packit fcad23
    case HRSTORE_UNITS:
Packit fcad23
        if (store_idx > NETSNMP_MEM_TYPE_MAX)
Packit fcad23
#if HRFS_HAS_FRSIZE
Packit fcad23
            long_return = stat_buf.f_frsize;
Packit fcad23
#else
Packit fcad23
            long_return = stat_buf.f_bsize;
Packit fcad23
#endif
Packit fcad23
        else {
Packit fcad23
            if ( !mem || mem->units == -1 )
Packit fcad23
                goto try_next;
Packit fcad23
            long_return = mem->units;
Packit fcad23
        }
Packit fcad23
        return (u_char *) & long_return;
Packit fcad23
    case HRSTORE_SIZE:
Packit fcad23
        if (store_idx > NETSNMP_MEM_TYPE_MAX)
Packit fcad23
            long_return = stat_buf.f_blocks;
Packit fcad23
        else {
Packit fcad23
            if ( !mem || mem->size == -1 )
Packit fcad23
                goto try_next;
Packit fcad23
            long_return = mem->size;
Packit fcad23
        }
Packit fcad23
        return (u_char *) & long_return;
Packit fcad23
    case HRSTORE_USED:
Packit fcad23
        if (store_idx > NETSNMP_MEM_TYPE_MAX)
Packit fcad23
            long_return = (stat_buf.f_blocks - stat_buf.f_bfree);
Packit fcad23
        else {
Packit fcad23
            if ( !mem || mem->size == -1 || mem->free == -1 )
Packit fcad23
                goto try_next;
Packit fcad23
            long_return = mem->size - mem->free;
Packit fcad23
        }
Packit fcad23
        return (u_char *) & long_return;
Packit fcad23
    case HRSTORE_FAILS:
Packit fcad23
        if (store_idx > NETSNMP_MEM_TYPE_MAX)
Packit fcad23
#if NETSNMP_NO_DUMMY_VALUES
Packit fcad23
	    goto try_next;
Packit fcad23
#else
Packit fcad23
            long_return = 0;
Packit fcad23
#endif
Packit fcad23
        else {
Packit fcad23
            if ( !mem || mem->other == -1 )
Packit fcad23
                goto try_next;
Packit fcad23
            long_return = mem->other;
Packit fcad23
        }
Packit fcad23
        return (u_char *) & long_return;
Packit fcad23
    default:
Packit fcad23
        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrstore\n",
Packit fcad23
                    vp->magic));
Packit fcad23
    }
Packit fcad23
    return NULL;
Packit fcad23
Packit fcad23
  try_next:
Packit fcad23
    if (!exact)
Packit fcad23
        goto really_try_next;
Packit fcad23
Packit fcad23
    return NULL;
Packit fcad23
}
Packit fcad23
Packit fcad23
Packit fcad23
        /*********************
Packit fcad23
	 *
Packit fcad23
	 *  Internal implementation functions
Packit fcad23
	 *
Packit fcad23
	 *********************/
Packit fcad23
Packit fcad23
static int      HRS_index;
Packit fcad23
Packit fcad23
void
Packit fcad23
Init_HR_Store(void)
Packit fcad23
{
Packit fcad23
    HRS_index = 0;
Packit fcad23
    Init_HR_FileSys();
Packit fcad23
}
Packit fcad23
Packit fcad23
int
Packit fcad23
Get_Next_HR_Store(void)
Packit fcad23
{
Packit fcad23
    /*
Packit fcad23
     * File-based storage 
Packit fcad23
     */
Packit fcad23
	for (;;) {
Packit fcad23
    	HRS_index = Get_Next_HR_FileSys();
Packit fcad23
		if (HRS_index >= 0) {
Packit fcad23
			if (!(netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID, 
Packit fcad23
							NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES) && 
Packit Service 2ecd3d
						Check_HR_FileSys_NFS())) {
Packit fcad23
				return HRS_index + NETSNMP_MEM_TYPE_MAX;	
Packit fcad23
			}
Packit fcad23
		} else {
Packit fcad23
			return -1;
Packit fcad23
		}	
Packit fcad23
	}
Packit fcad23
}
Packit fcad23
Packit fcad23
#if 0
Packit fcad23
void
Packit fcad23
sol_get_swapinfo(int *totalP, int *usedP)
Packit fcad23
{
Packit fcad23
    struct anoninfo ainfo;
Packit fcad23
Packit fcad23
    if (swapctl(SC_AINFO, &ainfo) < 0) {
Packit fcad23
        *totalP = *usedP = 0;
Packit fcad23
        return;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    *totalP = ainfo.ani_max;
Packit fcad23
    *usedP = ainfo.ani_resv;
Packit fcad23
}
Packit fcad23
#endif                          /* solaris2 */
Packit fcad23
Packit fcad23
#ifdef WIN32
Packit fcad23
char *win_realpath(const char *file_name, char *resolved_name)
Packit fcad23
{
Packit fcad23
	char szFile[_MAX_PATH + 1];
Packit fcad23
	char *pszRet;
Packit fcad23
 	
Packit fcad23
	pszRet = _fullpath(szFile, resolved_name, MAX_PATH);
Packit fcad23
 	
Packit fcad23
	return pszRet;  
Packit fcad23
}
Packit fcad23
Packit fcad23
static int win_statfs (const char *path, struct win_statfs *buf)
Packit fcad23
{
Packit fcad23
    HINSTANCE h;
Packit fcad23
    FARPROC f;
Packit fcad23
    int retval = 0;
Packit fcad23
    char tmp [MAX_PATH], resolved_path [MAX_PATH];
Packit fcad23
    GetFullPathName(path, MAX_PATH, resolved_path, NULL);
Packit fcad23
    /* TODO - Fix this! The realpath macro needs defined
Packit fcad23
     * or rewritten into the function.
Packit fcad23
     */
Packit fcad23
    
Packit fcad23
    win_realpath(path, resolved_path);
Packit fcad23
    
Packit fcad23
    if (!resolved_path)
Packit fcad23
    	retval = - 1;
Packit fcad23
    else {
Packit fcad23
    	/* check whether GetDiskFreeSpaceExA is supported */
Packit fcad23
        h = LoadLibraryA ("kernel32.dll");
Packit fcad23
        if (h)
Packit fcad23
			f = GetProcAddress (h, "GetDiskFreeSpaceExA");
Packit fcad23
        else
Packit fcad23
        	f = NULL;
Packit fcad23
		
Packit fcad23
        if (f) {
Packit fcad23
			ULARGE_INTEGER bytes_free, bytes_total, bytes_free2;
Packit fcad23
            if (!f (resolved_path, &bytes_free2, &bytes_total, &bytes_free)) {
Packit fcad23
				errno = ENOENT;
Packit fcad23
				retval = - 1;
Packit fcad23
			} else {
Packit fcad23
				buf -> f_bsize = FAKED_BLOCK_SIZE;
Packit fcad23
				buf -> f_bfree = (bytes_free.QuadPart) / FAKED_BLOCK_SIZE;
Packit fcad23
				buf -> f_files = buf -> f_blocks = (bytes_total.QuadPart) / FAKED_BLOCK_SIZE;
Packit fcad23
				buf -> f_ffree = buf -> f_bavail = (bytes_free2.QuadPart) / FAKED_BLOCK_SIZE;
Packit fcad23
			}
Packit fcad23
		} else {
Packit fcad23
			DWORD sectors_per_cluster, bytes_per_sector;
Packit fcad23
			if (h) FreeLibrary (h);
Packit fcad23
			if (!GetDiskFreeSpaceA (resolved_path, &sectors_per_cluster,
Packit fcad23
					&bytes_per_sector, &buf -> f_bavail, &buf -> f_blocks)) {
Packit fcad23
                errno = ENOENT;
Packit fcad23
                retval = - 1;
Packit fcad23
            } else {
Packit fcad23
                buf -> f_bsize = sectors_per_cluster * bytes_per_sector;
Packit fcad23
                buf -> f_files = buf -> f_blocks;
Packit fcad23
                buf -> f_ffree = buf -> f_bavail;
Packit fcad23
                buf -> f_bfree = buf -> f_bavail;
Packit fcad23
            }
Packit fcad23
		}
Packit fcad23
		if (h) FreeLibrary (h);
Packit fcad23
	}
Packit fcad23
Packit fcad23
	/* get the FS volume information */
Packit fcad23
	if (strspn (":", resolved_path) > 0) resolved_path [3] = '\0'; /* we want only the root */    
Packit fcad23
	if (GetVolumeInformation (resolved_path, NULL, 0, &buf -> f_fsid, &buf -> f_namelen, 
Packit fcad23
									NULL, tmp, MAX_PATH)) {
Packit fcad23
		if (strcasecmp ("NTFS", tmp) == 0) {
Packit fcad23
			buf -> f_type = NTFS_SUPER_MAGIC;
Packit fcad23
		} else {
Packit fcad23
			buf -> f_type = MSDOS_SUPER_MAGIC;
Packit fcad23
		}
Packit fcad23
	} else {
Packit fcad23
		errno = ENOENT;
Packit fcad23
		retval = - 1;
Packit fcad23
	}
Packit fcad23
	return retval;
Packit fcad23
}
Packit fcad23
#endif	/* WIN32 */