Blame agent/mibgroup/host/hr_partition.c

Packit fcad23
/*
Packit fcad23
 *  Host Resources MIB - partition device group implementation - hr_partition.c
Packit fcad23
 *
Packit fcad23
 */
Packit fcad23
/* Portions of this file are subject to the following copyright(s).  See
Packit fcad23
 * the Net-SNMP's COPYING file for more details and other copyrights
Packit fcad23
 * that may apply:
Packit fcad23
 */
Packit fcad23
/*
Packit fcad23
 * Portions of this file are copyrighted by:
Packit fcad23
 * Copyright (C) 2007 Apple, Inc. All rights reserved.
Packit fcad23
 * Use is subject to license terms specified in the COPYING file
Packit fcad23
 * distributed with the Net-SNMP package.
Packit fcad23
 */
Packit fcad23
Packit fcad23
#include <net-snmp/net-snmp-config.h>
Packit fcad23
#include <fcntl.h>
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_UNISTD_H
Packit fcad23
#include <unistd.h>
Packit fcad23
#endif
Packit fcad23
#include <errno.h>
Packit fcad23
Packit fcad23
#include "host_res.h"
Packit fcad23
#include "hr_partition.h"
Packit fcad23
#include "hr_filesys.h"
Packit fcad23
#include "hr_disk.h"
Packit fcad23
Packit fcad23
#include <sys/stat.h>
Packit fcad23
Packit fcad23
#define HRP_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
static int      HRP_savedDiskIndex;
Packit fcad23
static int      HRP_savedPartIndex;
Packit fcad23
static char     HRP_savedName[1024];
Packit fcad23
#ifdef NETSNMP_CAN_GET_DISK_LABEL
Packit fcad23
static char     HRP_savedLabel[1024];
Packit fcad23
#endif
Packit fcad23
#ifdef darwin
Packit fcad23
extern int
Packit fcad23
Get_HR_Disk_Label(char *string, size_t str_len, const char *devfull);
Packit fcad23
#endif
Packit fcad23
Packit fcad23
static int      HRP_DiskIndex;
Packit fcad23
Packit fcad23
static void     Save_HR_Partition(int, int);
Packit fcad23
Packit fcad23
Packit fcad23
        /*********************
Packit fcad23
	 *
Packit fcad23
	 *  Initialisation & common implementation functions
Packit fcad23
	 *
Packit fcad23
	 *********************/
Packit fcad23
Packit fcad23
static void     Init_HR_Partition(void);
Packit fcad23
static int      Get_Next_HR_Partition(void);
Packit fcad23
Packit fcad23
Packit fcad23
#define	HRPART_INDEX		1
Packit fcad23
#define	HRPART_LABEL		2
Packit fcad23
#define	HRPART_ID		3
Packit fcad23
#define	HRPART_SIZE		4
Packit fcad23
#define	HRPART_FSIDX		5
Packit fcad23
Packit fcad23
struct variable4 hrpartition_variables[] = {
Packit fcad23
    {HRPART_INDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
Packit fcad23
     var_hrpartition, 2, {1, 1}},
Packit fcad23
    {HRPART_LABEL, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
Packit fcad23
     var_hrpartition, 2, {1, 2}},
Packit fcad23
    {HRPART_ID, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
Packit fcad23
     var_hrpartition, 2, {1, 3}},
Packit fcad23
    {HRPART_SIZE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
Packit fcad23
     var_hrpartition, 2, {1, 4}},
Packit fcad23
    {HRPART_FSIDX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
Packit fcad23
     var_hrpartition, 2, {1, 5}}
Packit fcad23
};
Packit fcad23
oid             hrpartition_variables_oid[] =
Packit fcad23
    { 1, 3, 6, 1, 2, 1, 25, 3, 7 };
Packit fcad23
Packit fcad23
Packit fcad23
void
Packit fcad23
init_hr_partition(void)
Packit fcad23
{
Packit fcad23
    REGISTER_MIB("host/hr_partition", hrpartition_variables, variable4,
Packit fcad23
                 hrpartition_variables_oid);
Packit fcad23
}
Packit fcad23
Packit fcad23
Packit fcad23
/*
Packit fcad23
 * header_hrpartition(...
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
int
Packit fcad23
header_hrpartition(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 HRPART_DISK_NAME_LENGTH		11
Packit fcad23
#define HRPART_ENTRY_NAME_LENGTH	12
Packit fcad23
    oid             newname[MAX_OID_LEN];
Packit fcad23
    int             part_idx, LowDiskIndex = -1, LowPartIndex = -1;
Packit fcad23
    int             result;
Packit fcad23
Packit fcad23
    DEBUGMSGTL(("host/hr_partition", "var_hrpartition: "));
Packit fcad23
    DEBUGMSGOID(("host/hr_partition", name, *length));
Packit fcad23
    DEBUGMSG(("host/hr_partition", " %d\n", exact));
Packit fcad23
Packit fcad23
    memcpy((char *) newname, (char *) vp->name,
Packit fcad23
           (int) vp->namelen * sizeof(oid));
Packit fcad23
    /*
Packit fcad23
     * Find "next" partition entry 
Packit fcad23
     */
Packit fcad23
Packit fcad23
    Init_HR_Disk();
Packit fcad23
    Init_HR_Partition();
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     *  Find the "next" disk and partition entries.
Packit fcad23
     *  If we're in the middle of the table, then there's
Packit fcad23
     *     no point in examining earlier disks, so set the
Packit fcad23
     *     starting disk to that of the variable being queried.
Packit fcad23
     *
Packit fcad23
     *  If we've moved from one column of the table to another,
Packit fcad23
     *     then we need to start at the beginning again.
Packit fcad23
     *     (i.e. the 'compare' fails to match)
Packit fcad23
     *  Similarly if we're at the start of the table
Packit fcad23
     *     (i.e. *length is too short to be a full instance)
Packit fcad23
     */
Packit fcad23
Packit fcad23
    if ((snmp_oid_compare(vp->name, vp->namelen, name, vp->namelen) == 0)
Packit fcad23
        && (*length > HRPART_DISK_NAME_LENGTH)) {
Packit fcad23
        LowDiskIndex =
Packit fcad23
            (name[HRPART_DISK_NAME_LENGTH] &
Packit fcad23
             ((1 << HRDEV_TYPE_SHIFT) - 1));
Packit fcad23
Packit fcad23
        DEBUGMSGTL(("host/hr_partition", "... low index %d\n", LowDiskIndex));
Packit fcad23
        while (HRP_DiskIndex < LowDiskIndex) {
Packit fcad23
            Init_HR_Partition();        /* moves to next disk */
Packit fcad23
            if (HRP_DiskIndex == -1)
Packit fcad23
                return (MATCH_FAILED);
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
Packit fcad23
    for (;;) {
Packit fcad23
        part_idx = Get_Next_HR_Partition();
Packit fcad23
        DEBUGMSGTL(("host/hr_partition", "... part index %d\n", part_idx));
Packit fcad23
        if (part_idx == 0)
Packit fcad23
            break;
Packit fcad23
        newname[HRPART_DISK_NAME_LENGTH] =
Packit fcad23
            (HRDEV_DISK << HRDEV_TYPE_SHIFT) + HRP_DiskIndex;
Packit fcad23
        newname[HRPART_ENTRY_NAME_LENGTH] = part_idx;
Packit fcad23
        result = snmp_oid_compare(name, *length, newname, vp->namelen + 2);
Packit fcad23
        if (exact && (result == 0)) {
Packit fcad23
            Save_HR_Partition(HRP_DiskIndex, part_idx);
Packit fcad23
            LowDiskIndex = HRP_DiskIndex;
Packit fcad23
            LowPartIndex = part_idx;
Packit fcad23
            break;
Packit fcad23
        }
Packit fcad23
        if (!exact && (result < 0)) {
Packit fcad23
            if (LowPartIndex == -1) {
Packit fcad23
                Save_HR_Partition(HRP_DiskIndex, part_idx);
Packit fcad23
                LowDiskIndex = HRP_DiskIndex;
Packit fcad23
                LowPartIndex = part_idx;
Packit fcad23
            } else if (LowDiskIndex < HRP_DiskIndex)
Packit fcad23
                break;
Packit fcad23
            else if (part_idx < LowPartIndex) {
Packit fcad23
                Save_HR_Partition(HRP_DiskIndex, part_idx);
Packit fcad23
                LowDiskIndex = HRP_DiskIndex;
Packit fcad23
                LowPartIndex = part_idx;
Packit fcad23
            }
Packit fcad23
#ifdef HRP_MONOTONICALLY_INCREASING
Packit fcad23
            break;
Packit fcad23
#endif
Packit fcad23
        }
Packit fcad23
    }
Packit fcad23
Packit fcad23
    if (LowPartIndex == -1) {
Packit fcad23
        DEBUGMSGTL(("host/hr_partition", "... index out of range\n"));
Packit fcad23
        return (MATCH_FAILED);
Packit fcad23
    }
Packit fcad23
Packit fcad23
    newname[HRPART_DISK_NAME_LENGTH] =
Packit fcad23
        (HRDEV_DISK << HRDEV_TYPE_SHIFT) + LowDiskIndex;
Packit fcad23
    newname[HRPART_ENTRY_NAME_LENGTH] = LowPartIndex;
Packit fcad23
    memcpy((char *) name, (char *) newname,
Packit fcad23
           ((int) vp->namelen + 2) * sizeof(oid));
Packit fcad23
    *length = vp->namelen + 2;
Packit fcad23
    *write_method = (WriteMethod*)0;
Packit fcad23
    *var_len = sizeof(long);    /* default to 'long' results */
Packit fcad23
Packit fcad23
    DEBUGMSGTL(("host/hr_partition", "... get partition stats "));
Packit fcad23
    DEBUGMSGOID(("host/hr_partition", name, *length));
Packit fcad23
    DEBUGMSG(("host/hr_partition", "\n"));
Packit fcad23
    return LowPartIndex;
Packit fcad23
}
Packit fcad23
Packit fcad23
Packit fcad23
        /*********************
Packit fcad23
	 *
Packit fcad23
	 *  System specific implementation functions
Packit fcad23
	 *
Packit fcad23
	 *********************/
Packit fcad23
Packit fcad23
Packit fcad23
u_char         *
Packit fcad23
var_hrpartition(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             part_idx;
Packit fcad23
    static char     string[1024];
Packit fcad23
    struct stat     stat_buf;
Packit fcad23
Packit fcad23
    part_idx =
Packit fcad23
        header_hrpartition(vp, name, length, exact, var_len, write_method);
Packit fcad23
    if (part_idx == MATCH_FAILED)
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    if (stat(HRP_savedName, &stat_buf) == -1)
Packit fcad23
        return NULL;
Packit fcad23
Packit fcad23
    switch (vp->magic) {
Packit fcad23
    case HRPART_INDEX:
Packit fcad23
        long_return = part_idx;
Packit fcad23
        return (u_char *) & long_return;
Packit fcad23
    case HRPART_LABEL:
Packit fcad23
#ifdef NETSNMP_CAN_GET_DISK_LABEL
Packit fcad23
        *var_len = strlen(HRP_savedLabel);
Packit fcad23
        return (u_char *) HRP_savedLabel;
Packit fcad23
#else
Packit fcad23
        *var_len = strlen(HRP_savedName);
Packit fcad23
        return (u_char *) HRP_savedName;
Packit fcad23
#endif
Packit fcad23
    case HRPART_ID:            /* Use the device number */
Packit fcad23
        sprintf(string, "0x%x", (int) stat_buf.st_rdev);
Packit fcad23
        *var_len = strlen(string);
Packit fcad23
        return (u_char *) string;
Packit fcad23
    case HRPART_SIZE:
Packit fcad23
        /*
Packit fcad23
         * XXX - based on single partition assumption 
Packit fcad23
         */
Packit fcad23
        long_return = Get_FSSize(HRP_savedName);
Packit fcad23
        return (u_char *) & long_return;
Packit fcad23
    case HRPART_FSIDX:
Packit fcad23
        long_return = Get_FSIndex(HRP_savedName);
Packit fcad23
        return (u_char *) & long_return;
Packit fcad23
    default:
Packit fcad23
        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrpartition\n",
Packit fcad23
                    vp->magic));
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      HRP_index;
Packit fcad23
Packit fcad23
static void
Packit fcad23
Init_HR_Partition(void)
Packit fcad23
{
Packit fcad23
    DEBUGMSGTL(("host/hr_partition", "Init_HR_Partition\n"));
Packit fcad23
    HRP_DiskIndex = Get_Next_HR_Disk();
Packit fcad23
    if (HRP_DiskIndex != -1)
Packit fcad23
        HRP_DiskIndex &= ((1 << HRDEV_TYPE_SHIFT) - 1);
Packit fcad23
    DEBUGMSGTL(("host/hr_partition", "...  %d\n",HRP_DiskIndex));
Packit fcad23
Packit fcad23
    HRP_index = -1;
Packit fcad23
}
Packit fcad23
Packit fcad23
static int
Packit fcad23
Get_Next_HR_Partition(void)
Packit fcad23
{
Packit fcad23
    char            string[1024];
Packit fcad23
    int             fd;
Packit fcad23
Packit fcad23
    DEBUGMSGTL(("host/hr_partition", "Get_Next_HR_Partition %d\n",HRP_DiskIndex));
Packit fcad23
    if (HRP_DiskIndex == -1) {
Packit fcad23
        return 0;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    HRP_index++;
Packit fcad23
    while (Get_Next_HR_Disk_Partition(string, sizeof(string), HRP_index) != -1) {
Packit fcad23
        DEBUGMSGTL(("host/hr_partition",
Packit fcad23
                    "Get_Next_HR_Partition: %s (:%d)\n",
Packit fcad23
                    string, HRP_index));
Packit fcad23
Packit fcad23
#ifdef O_NDELAY
Packit fcad23
        fd = open(string, O_RDONLY|O_NDELAY);
Packit fcad23
#else
Packit fcad23
        fd = open(string, O_RDONLY);
Packit fcad23
#endif
Packit fcad23
        if (fd != -1) {
Packit fcad23
            close(fd);
Packit fcad23
            return HRP_index + 1;
Packit fcad23
        } else if (errno == EBUSY) {
Packit fcad23
            return HRP_index + 1;
Packit fcad23
        }
Packit fcad23
        HRP_index++;
Packit fcad23
    }
Packit fcad23
Packit fcad23
    /*
Packit fcad23
     * Finished with this disk, try the next
Packit fcad23
     */
Packit fcad23
    Init_HR_Partition();
Packit fcad23
    return (Get_Next_HR_Partition());
Packit fcad23
}
Packit fcad23
Packit fcad23
static void
Packit fcad23
Save_HR_Partition(int disk_idx, int part_idx)
Packit fcad23
{
Packit fcad23
    HRP_savedDiskIndex = disk_idx;
Packit fcad23
    HRP_savedPartIndex = part_idx;
Packit fcad23
    (void) Get_Next_HR_Disk_Partition(HRP_savedName, sizeof(HRP_savedName), HRP_index);
Packit fcad23
#ifdef NETSNMP_CAN_GET_DISK_LABEL
Packit fcad23
    (void) Get_HR_Disk_Label(HRP_savedLabel, sizeof(HRP_savedLabel), HRP_savedName);
Packit fcad23
#endif
Packit fcad23
}