hr_partition.c
上传用户:wxp200602
上传日期:2007-10-30
资源大小:4028k
文件大小:8k
源码类别:

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  *  Host Resources MIB - partition device group implementation - hr_partition.c
  3.  *
  4.  */
  5. #include <net-snmp/net-snmp-config.h>
  6. #include <fcntl.h>
  7. #if HAVE_STRING_H
  8. #include <string.h>
  9. #else
  10. #include <strings.h>
  11. #endif
  12. #if HAVE_UNISTD_H
  13. #include <unistd.h>
  14. #endif
  15. #include <errno.h>
  16. #include "host_res.h"
  17. #include "hr_partition.h"
  18. #include "hr_filesys.h"
  19. #include "hr_disk.h"
  20. #include <sys/stat.h>
  21. #define HRP_MONOTONICALLY_INCREASING
  22.         /*********************
  23.  *
  24.  *  Kernel & interface information,
  25.  *   and internal forward declarations
  26.  *
  27.  *********************/
  28. static int      HRP_savedDiskIndex;
  29. static int      HRP_savedPartIndex;
  30. static char     HRP_savedName[1024];
  31. static int      HRP_DiskIndex;
  32. static void     Save_HR_Partition(int, int);
  33.         /*********************
  34.  *
  35.  *  Initialisation & common implementation functions
  36.  *
  37.  *********************/
  38. static void     Init_HR_Partition(void);
  39. static int      Get_Next_HR_Partition(void);
  40. int             header_hrpartition(struct variable *, oid *, size_t *, int,
  41.                                    size_t *, WriteMethod **);
  42. #define HRPART_INDEX 1
  43. #define HRPART_LABEL 2
  44. #define HRPART_ID 3
  45. #define HRPART_SIZE 4
  46. #define HRPART_FSIDX 5
  47. struct variable4 hrpartition_variables[] = {
  48.     {HRPART_INDEX, ASN_INTEGER, RONLY, var_hrpartition, 2, {1, 1}},
  49.     {HRPART_LABEL, ASN_OCTET_STR, RONLY, var_hrpartition, 2, {1, 2}},
  50.     {HRPART_ID, ASN_OCTET_STR, RONLY, var_hrpartition, 2, {1, 3}},
  51.     {HRPART_SIZE, ASN_INTEGER, RONLY, var_hrpartition, 2, {1, 4}},
  52.     {HRPART_FSIDX, ASN_INTEGER, RONLY, var_hrpartition, 2, {1, 5}}
  53. };
  54. oid             hrpartition_variables_oid[] =
  55.     { 1, 3, 6, 1, 2, 1, 25, 3, 7 };
  56. void
  57. init_hr_partition(void)
  58. {
  59.     REGISTER_MIB("host/hr_partition", hrpartition_variables, variable4,
  60.                  hrpartition_variables_oid);
  61. }
  62. /*
  63.  * header_hrpartition(...
  64.  * Arguments:
  65.  * vp     IN      - pointer to variable entry that points here
  66.  * name    IN/OUT  - IN/name requested, OUT/name found
  67.  * length  IN/OUT  - length of IN/OUT oid's 
  68.  * exact   IN      - TRUE if an exact match was requested
  69.  * var_len OUT     - length of variable or 0 if function returned
  70.  * write_method
  71.  * 
  72.  */
  73. int
  74. header_hrpartition(struct variable *vp,
  75.                    oid * name,
  76.                    size_t * length,
  77.                    int exact,
  78.                    size_t * var_len, WriteMethod ** write_method)
  79. {
  80. #define HRPART_DISK_NAME_LENGTH 11
  81. #define HRPART_ENTRY_NAME_LENGTH 12
  82.     oid             newname[MAX_OID_LEN];
  83.     int             part_idx, LowDiskIndex = -1, LowPartIndex = -1;
  84.     int             result;
  85.     DEBUGMSGTL(("host/hr_partition", "var_hrpartition: "));
  86.     DEBUGMSGOID(("host/hr_partition", name, *length));
  87.     DEBUGMSG(("host/hr_partition", " %dn", exact));
  88.     memcpy((char *) newname, (char *) vp->name,
  89.            (int) vp->namelen * sizeof(oid));
  90.     /*
  91.      * Find "next" partition entry 
  92.      */
  93.     Init_HR_Disk();
  94.     Init_HR_Partition();
  95.     /*
  96.      *  Find the "next" disk and partition entries.
  97.      *  If we're in the middle of the table, then there's
  98.      *     no point in examining earlier disks, so set the
  99.      *     starting disk to that of the variable being queried.
  100.      *
  101.      *  If we've moved from one column of the table to another,
  102.      *     then we need to start at the beginning again.
  103.      *     (i.e. the 'compare' fails to match)
  104.      *  Similarly if we're at the start of the table
  105.      *     (i.e. *length is too short to be a full instance)
  106.      */
  107.     if ((snmp_oid_compare(vp->name, vp->namelen, name, vp->namelen) == 0)
  108.         && (*length > HRPART_DISK_NAME_LENGTH)) {
  109.         LowDiskIndex =
  110.             (name[HRPART_DISK_NAME_LENGTH] &
  111.              ((1 << HRDEV_TYPE_SHIFT) - 1));
  112.         while (HRP_DiskIndex < LowDiskIndex) {
  113.             Init_HR_Partition();        /* moves to next disk */
  114.             if (HRP_DiskIndex == -1)
  115.                 return (MATCH_FAILED);
  116.         }
  117.     }
  118.     for (;;) {
  119.         part_idx = Get_Next_HR_Partition();
  120.         if (part_idx == 0)
  121.             break;
  122.         newname[HRPART_DISK_NAME_LENGTH] =
  123.             (HRDEV_DISK << HRDEV_TYPE_SHIFT) + HRP_DiskIndex;
  124.         newname[HRPART_ENTRY_NAME_LENGTH] = part_idx;
  125.         result = snmp_oid_compare(name, *length, newname, vp->namelen + 2);
  126.         if (exact && (result == 0)) {
  127.             Save_HR_Partition(HRP_DiskIndex, part_idx);
  128.             LowDiskIndex = HRP_DiskIndex;
  129.             LowPartIndex = part_idx;
  130.             break;
  131.         }
  132.         if (!exact && (result < 0)) {
  133.             if (LowPartIndex == -1) {
  134.                 Save_HR_Partition(HRP_DiskIndex, part_idx);
  135.                 LowDiskIndex = HRP_DiskIndex;
  136.                 LowPartIndex = part_idx;
  137.             } else if (LowDiskIndex < HRP_DiskIndex)
  138.                 break;
  139.             else if (part_idx < LowPartIndex) {
  140.                 Save_HR_Partition(HRP_DiskIndex, part_idx);
  141.                 LowDiskIndex = HRP_DiskIndex;
  142.                 LowPartIndex = part_idx;
  143.             }
  144. #ifdef HRP_MONOTONICALLY_INCREASING
  145.             break;
  146. #endif
  147.         }
  148.     }
  149.     if (LowPartIndex == -1) {
  150.         DEBUGMSGTL(("host/hr_partition", "... index out of rangen"));
  151.         return (MATCH_FAILED);
  152.     }
  153.     newname[HRPART_DISK_NAME_LENGTH] =
  154.         (HRDEV_DISK << HRDEV_TYPE_SHIFT) + LowDiskIndex;
  155.     newname[HRPART_ENTRY_NAME_LENGTH] = LowPartIndex;
  156.     memcpy((char *) name, (char *) newname,
  157.            ((int) vp->namelen + 2) * sizeof(oid));
  158.     *length = vp->namelen + 2;
  159.     *write_method = 0;
  160.     *var_len = sizeof(long);    /* default to 'long' results */
  161.     DEBUGMSGTL(("host/hr_partition", "... get partition stats "));
  162.     DEBUGMSGOID(("host/hr_partition", name, *length));
  163.     DEBUGMSG(("host/hr_partition", "n"));
  164.     return LowPartIndex;
  165. }
  166.         /*********************
  167.  *
  168.  *  System specific implementation functions
  169.  *
  170.  *********************/
  171. u_char         *
  172. var_hrpartition(struct variable * vp,
  173.                 oid * name,
  174.                 size_t * length,
  175.                 int exact, size_t * var_len, WriteMethod ** write_method)
  176. {
  177.     int             part_idx;
  178.     static char     string[1024];
  179.     struct stat     stat_buf;
  180.     part_idx =
  181.         header_hrpartition(vp, name, length, exact, var_len, write_method);
  182.     if (part_idx == MATCH_FAILED)
  183.         return NULL;
  184.     if (stat(HRP_savedName, &stat_buf) == -1)
  185.         return NULL;
  186.     switch (vp->magic) {
  187.     case HRPART_INDEX:
  188.         long_return = part_idx;
  189.         return (u_char *) & long_return;
  190.     case HRPART_LABEL:
  191.         *var_len = strlen(HRP_savedName);
  192.         return (u_char *) HRP_savedName;
  193.     case HRPART_ID:            /* Use the device number */
  194.         sprintf(string, "0x%x", (int) stat_buf.st_rdev);
  195.         *var_len = strlen(string);
  196.         return (u_char *) string;
  197.     case HRPART_SIZE:
  198.         /*
  199.          * XXX - based on single partition assumption 
  200.          */
  201.         long_return = Get_FSSize(HRP_savedName);
  202.         return (u_char *) & long_return;
  203.     case HRPART_FSIDX:
  204.         long_return = Get_FSIndex(HRP_savedName);
  205.         return (u_char *) & long_return;
  206.     default:
  207.         DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrpartitionn",
  208.                     vp->magic));
  209.     }
  210.     return NULL;
  211. }
  212.         /*********************
  213.  *
  214.  *  Internal implementation functions
  215.  *
  216.  *********************/
  217. static int      HRP_index;
  218. static void
  219. Init_HR_Partition(void)
  220. {
  221.     HRP_DiskIndex = Get_Next_HR_Disk();
  222.     if (HRP_DiskIndex != -1)
  223.         HRP_DiskIndex &= ((1 << HRDEV_TYPE_SHIFT) - 1);
  224.     HRP_index = -1;
  225. }
  226. static int
  227. Get_Next_HR_Partition(void)
  228. {
  229.     char            string[1024];
  230.     int             fd;
  231.     if (HRP_DiskIndex == -1) {
  232.         return 0;
  233.     }
  234.     HRP_index++;
  235.     while (Get_Next_HR_Disk_Partition(string, sizeof(string), HRP_index) != -1) {
  236.         DEBUGMSGTL(("host/hr_partition",
  237.                     "Get_Next_HR_Partition: %s (:%d)n",
  238.                     string, HRP_index));
  239. #ifdef O_NDELAY
  240.         fd = open(string, O_RDONLY|O_NDELAY);
  241. #else
  242.         fd = open(string, O_RDONLY);
  243. #endif
  244.         if (fd != -1) {
  245.             close(fd);
  246.             return HRP_index + 1;
  247.         } else if (errno == EBUSY) {
  248.             return HRP_index + 1;
  249.         }
  250.         HRP_index++;
  251.     }
  252.     /*
  253.      * Finished with this disk, try the next
  254.      */
  255.     Init_HR_Partition();
  256.     return (Get_Next_HR_Partition());
  257. }
  258. static void
  259. Save_HR_Partition(int disk_idx, int part_idx)
  260. {
  261.     HRP_savedDiskIndex = disk_idx;
  262.     HRP_savedPartIndex = part_idx;
  263.     (void) Get_Next_HR_Disk_Partition(HRP_savedName, sizeof(HRP_savedName), HRP_index);
  264. }