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

SNMP编程

开发平台:

Unix_Linux

  1. /*
  2.  *  Host Resources MIB - disk device group implementation - hr_disk.c
  3.  *
  4.  */
  5. #include <net-snmp/net-snmp-config.h>
  6. #include "host_res.h"
  7. #include "hr_disk.h"
  8. #if HAVE_STRING_H
  9. #include <string.h>
  10. #else
  11. #include <strings.h>
  12. #endif
  13. #include <fcntl.h>
  14. #if HAVE_UNISTD_H
  15. #include <unistd.h>
  16. #endif
  17. #if HAVE_KVM_H
  18. #include <kvm.h>
  19. #endif
  20. #if HAVE_DIRENT_H
  21. #include <dirent.h>
  22. #else
  23. # define dirent direct
  24. # if HAVE_SYS_NDIR_H
  25. #  include <sys/ndir.h>
  26. # endif
  27. # if HAVE_SYS_DIR_H
  28. #  include <sys/dir.h>
  29. # endif
  30. # if HAVE_NDIR_H
  31. #  include <ndir.h>
  32. # endif
  33. #endif
  34. #if HAVE_SYS_IOCTL_H
  35. #include <sys/ioctl.h>
  36. #endif
  37. #if HAVE_SYS_DKIO_H
  38. #include <sys/dkio.h>
  39. #endif
  40. #if HAVE_SYS_DISKIO_H           /* HP-UX only ? */
  41. #include <sys/diskio.h>
  42. #endif
  43. #if HAVE_LINUX_HDREG_H
  44. #include <linux/hdreg.h>
  45. #endif
  46. #if HAVE_SYS_DISKLABEL_H
  47. #define DKTYPENAMES
  48. #include <sys/disklabel.h>
  49. #endif
  50. #if TIME_WITH_SYS_TIME
  51. # include <sys/time.h>
  52. # include <time.h>
  53. #else
  54. # if HAVE_SYS_TIME_H
  55. #  include <sys/time.h>
  56. # else
  57. #  include <time.h>
  58. # endif
  59. #endif
  60. #if HAVE_LIMITS_H
  61. #include <limits.h>
  62. #endif
  63. #ifdef linux
  64. /*
  65.  * define BLKGETSIZE from <linux/fs.h>:
  66.  * Note: cannot include this file completely due to errors with redefinition
  67.  * of structures (at least with older linux versions) --jsf
  68.  */
  69. #define BLKGETSIZE _IO(0x12,96) /* return device size */
  70. #endif
  71. #include <net-snmp/agent/agent_read_config.h>
  72. #include <net-snmp/library/read_config.h>
  73. #define HRD_MONOTONICALLY_INCREASING
  74.         /*********************
  75.  *
  76.  *  Kernel & interface information,
  77.  *   and internal forward declarations
  78.  *
  79.  *********************/
  80. void            Init_HR_Disk(void);
  81. int             Get_Next_HR_Disk(void);
  82. int             Get_Next_HR_Disk_Partition(char *, size_t, int);
  83. static void     Add_HR_Disk_entry(const char *, int, int, int, int,
  84.                                   const char *, int, int);
  85. static void     Save_HR_Disk_General(void);
  86. static void     Save_HR_Disk_Specific(void);
  87. static int      Query_Disk(int, const char *);
  88. static int      Is_It_Writeable(void);
  89. static int      What_Type_Disk(void);
  90. static int      Is_It_Removeable(void);
  91. static const char *describe_disk(int);
  92. int             header_hrdisk(struct variable *, oid *, size_t *, int,
  93.                               size_t *, WriteMethod **);
  94. static int      HRD_type_index;
  95. static int      HRD_index;
  96. static char     HRD_savedModel[40];
  97. static long     HRD_savedCapacity = 1044;
  98. static int      HRD_savedFlags;
  99. static time_t   HRD_history[HRDEV_TYPE_MASK];
  100. #ifdef DIOC_DESCRIBE
  101. static disk_describe_type HRD_info;
  102. static capacity_type HRD_cap;
  103. static int      HRD_savedIntf_type;
  104. static int      HRD_savedDev_type;
  105. #endif
  106. #ifdef DKIOCINFO
  107. static struct dk_cinfo HRD_info;
  108. static struct dk_geom HRD_cap;
  109. static int      HRD_savedCtrl_type;
  110. #endif
  111. #ifdef HAVE_LINUX_HDREG_H
  112. static struct hd_driveid HRD_info;
  113. #endif
  114. #ifdef DIOCGDINFO
  115. static struct disklabel HRD_info;
  116. #endif
  117. static void     parse_disk_config(const char *, char *);
  118. static void     free_disk_config(void);
  119.         /*********************
  120.  *
  121.  *  Initialisation & common implementation functions
  122.  *
  123.  *********************/
  124. #define HRDISK_ACCESS 1
  125. #define HRDISK_MEDIA 2
  126. #define HRDISK_REMOVEABLE 3
  127. #define HRDISK_CAPACITY 4
  128. struct variable4 hrdisk_variables[] = {
  129.     {HRDISK_ACCESS, ASN_INTEGER, RONLY, var_hrdisk, 2, {1, 1}},
  130.     {HRDISK_MEDIA, ASN_INTEGER, RONLY, var_hrdisk, 2, {1, 2}},
  131.     {HRDISK_REMOVEABLE, ASN_INTEGER, RONLY, var_hrdisk, 2, {1, 3}},
  132.     {HRDISK_CAPACITY, ASN_INTEGER, RONLY, var_hrdisk, 2, {1, 4}}
  133. };
  134. oid             hrdisk_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 3, 6 };
  135. void
  136. init_hr_disk(void)
  137. {
  138.     int             i;
  139.     init_device[HRDEV_DISK] = Init_HR_Disk;
  140.     next_device[HRDEV_DISK] = Get_Next_HR_Disk;
  141.     save_device[HRDEV_DISK] = Save_HR_Disk_General;
  142. #ifdef HRD_MONOTONICALLY_INCREASING
  143.     dev_idx_inc[HRDEV_DISK] = 1;
  144. #endif
  145. #if defined(linux)
  146.     Add_HR_Disk_entry("/dev/hd%c%d", -1, -1, 'a', 'l', "/dev/hd%c", 1, 15);
  147.     Add_HR_Disk_entry("/dev/sd%c%d", -1, -1, 'a', 'p', "/dev/sd%c", 1, 15);
  148.     Add_HR_Disk_entry("/dev/md%d", -1, -1, 0, 3, "/dev/md%d", 0, 0);
  149.     Add_HR_Disk_entry("/dev/fd%d", -1, -1, 0, 1, "/dev/fd%d", 0, 0);
  150. #elif defined(hpux)
  151. #if defined(hpux10) || defined(hpux11)
  152.     Add_HR_Disk_entry("/dev/rdsk/c%dt%xd%d", 0, 1, 0, 15,
  153.                       "/dev/rdsk/c%dt%xd0", 0, 4);
  154. #else                           /* hpux9 */
  155.     Add_HR_Disk_entry("/dev/rdsk/c%dd%xs%d", 201, 201, 0, 15,
  156.                       "/dev/rdsk/c%dd%xs0", 0, 4);
  157. #endif
  158. #elif defined(solaris2)
  159.     Add_HR_Disk_entry("/dev/rdsk/c%dt%dd0s%d", 0, 7, 0, 15,
  160.                       "/dev/rdsk/c%dt%dd0s0", 0, 7);
  161.     Add_HR_Disk_entry("/dev/rdsk/c%dd%ds%d", 0, 7, 0, 15,
  162.                       "/dev/rdsk/c%dd%ds0", 0, 7);
  163. #elif defined(freebsd4) || defined(freebsd5)
  164.     Add_HR_Disk_entry("/dev/ad%ds%d%c", 0, 1, 1, 4, "/dev/ad%ds%d", 'a', 'h');
  165.     Add_HR_Disk_entry("/dev/da%ds%d%c", 0, 1, 1, 4, "/dev/da%ds%d", 'a', 'h');
  166. #elif defined(freebsd3)
  167.     Add_HR_Disk_entry("/dev/wd%ds%d%c", 0, 1, 1, 4, "/dev/wd%ds%d", 'a',
  168.                       'h');
  169.     Add_HR_Disk_entry("/dev/sd%ds%d%c", 0, 1, 1, 4, "/dev/sd%ds%d", 'a',
  170.                       'h');
  171. #elif defined(freebsd2)
  172.     Add_HR_Disk_entry("/dev/wd%d%c", -1, -1, 0, 3, "/dev/wd%d", 'a', 'h');
  173.     Add_HR_Disk_entry("/dev/sd%d%c", -1, -1, 0, 3, "/dev/sd%d", 'a', 'h');
  174. #elif defined(netbsd1)
  175.     Add_HR_Disk_entry("/dev/wd%d%c", -1, -1, 0, 3, "/dev/wd%dc", 'a', 'h');
  176.     Add_HR_Disk_entry("/dev/sd%d%c", -1, -1, 0, 3, "/dev/sd%dc", 'a', 'h');
  177. #endif
  178.     device_descr[HRDEV_DISK] = describe_disk;
  179.     HRD_savedModel[0] = '';
  180.     HRD_savedCapacity = 0;
  181.     for (i = 0; i < HRDEV_TYPE_MASK; ++i)
  182.         HRD_history[i] = -1;
  183.     REGISTER_MIB("host/hr_disk", hrdisk_variables, variable4,
  184.                  hrdisk_variables_oid);
  185.     snmpd_register_config_handler("ignoredisk", parse_disk_config,
  186.                                   free_disk_config, "name");
  187. }
  188. #define ITEM_STRING 1
  189. #define ITEM_SET 2
  190. #define ITEM_STAR 3
  191. #define ITEM_ANY 4
  192. typedef unsigned char details_set[32];
  193. typedef struct _conf_disk_item {
  194.     int             item_type;  /* ITEM_STRING, ITEM_SET, ITEM_STAR, ITEM_ANY */
  195.     void           *item_details;       /* content depends upon item_type */
  196.     struct _conf_disk_item *item_next;
  197. } conf_disk_item;
  198. typedef struct _conf_disk_list {
  199.     conf_disk_item *list_item;
  200.     struct _conf_disk_list *list_next;
  201. } conf_disk_list;
  202. static conf_disk_list *conf_list = NULL;
  203. static int      match_disk_config(const char *);
  204. static int      match_disk_config_item(const char *, conf_disk_item *);
  205. static void
  206. parse_disk_config(const char *token, char *cptr)
  207. {
  208.     conf_disk_list *d_new;
  209.     conf_disk_item *di_curr;
  210.     details_set    *d_set;
  211.     char           *name, *p, *d_str, c;
  212.     unsigned int    i, neg, c1, c2;
  213.     char           *st;
  214.     name = strtok_r(cptr, " t", &st);
  215.     if (!name) {
  216.         config_perror("Missing NAME parameter");
  217.         return;
  218.     }
  219.     d_new = (conf_disk_list *) malloc(sizeof(conf_disk_list));
  220.     if (!d_new) {
  221.         config_perror("Out of memory");
  222.         return;
  223.     }
  224.     di_curr = (conf_disk_item *) malloc(sizeof(conf_disk_item));
  225.     if (!di_curr) {
  226.         config_perror("Out of memory");
  227.         return;
  228.     }
  229.     d_new->list_item = di_curr;
  230.     for (;;) {
  231.         if (*name == '?') {
  232.             di_curr->item_type = ITEM_ANY;
  233.             di_curr->item_details = (void *) 0;
  234.             name++;
  235.         } else if (*name == '*') {
  236.             di_curr->item_type = ITEM_STAR;
  237.             di_curr->item_details = (void *) 0;
  238.             name++;
  239.         } else if (*name == '[') {
  240.             d_set = (details_set *) malloc(sizeof(details_set));
  241.             if (!d_set) {
  242.                 config_perror("Out of memory");
  243.                 return;
  244.             }
  245.             for (i = 0; i < sizeof(details_set); i++)
  246.                 (*d_set)[i] = (unsigned char) 0;
  247.             name++;
  248.             if (*name == '^' || *name == '!') {
  249.                 neg = 1;
  250.                 name++;
  251.             } else {
  252.                 neg = 0;
  253.             }
  254.             while (*name && *name != ']') {
  255.                 c1 = ((unsigned int) *name++) & 0xff;
  256.                 if (*name == '-' && *(name + 1) != ']') {
  257.                     name++;
  258.                     c2 = ((unsigned int) *name++) & 0xff;
  259.                 } else {
  260.                     c2 = c1;
  261.                 }
  262.                 for (i = c1; i <= c2; i++)
  263.                     (*d_set)[i / 8] |= (unsigned char) (1 << (i % 8));
  264.             }
  265.             if (*name != ']') {
  266.                 config_perror
  267.                     ("Syntax error in NAME: invalid set specified");
  268.                 return;
  269.             }
  270.             if (neg) {
  271.                 for (i = 0; i < sizeof(details_set); i++)
  272.                     (*d_set)[i] = (*d_set)[i] ^ (unsigned char) 0xff;
  273.             }
  274.             di_curr->item_type = ITEM_SET;
  275.             di_curr->item_details = (void *) d_set;
  276.             name++;
  277.         } else {
  278.             for (p = name;
  279.                  *p != '' && *p != '?' && *p != '*' && *p != '['; p++);
  280.             c = *p;
  281.             *p = '';
  282.             d_str = (char *) malloc(strlen(name) + 1);
  283.             if (!d_str) {
  284.                 config_perror("Out of memory");
  285.                 return;
  286.             }
  287.             strcpy(d_str, name);
  288.             *p = c;
  289.             di_curr->item_type = ITEM_STRING;
  290.             di_curr->item_details = (void *) d_str;
  291.             name = p;
  292.         }
  293.         if (!*name) {
  294.             di_curr->item_next = (conf_disk_item *) 0;
  295.             break;
  296.         }
  297.         di_curr->item_next =
  298.             (conf_disk_item *) malloc(sizeof(conf_disk_item));
  299.         if (!di_curr->item_next) {
  300.             config_perror("Out of memory");
  301.             return;
  302.         }
  303.         di_curr = di_curr->item_next;
  304.     }
  305.     d_new->list_next = conf_list;
  306.     conf_list = d_new;
  307. }
  308. static void
  309. free_disk_config(void)
  310. {
  311.     conf_disk_list *d_ptr = conf_list, *d_next;
  312.     conf_disk_item *di_ptr, *di_next;
  313.     while (d_ptr) {
  314.         d_next = d_ptr->list_next;
  315.         di_ptr = d_ptr->list_item;
  316.         while (di_ptr) {
  317.             di_next = di_ptr->item_next;
  318.             if (di_ptr->item_details)
  319.                 free(di_ptr->item_details);
  320.             free((void *) di_ptr);
  321.             di_ptr = di_next;
  322.         }
  323.         free((void *) d_ptr);
  324.         d_ptr = d_next;
  325.     }
  326.     conf_list = (conf_disk_list *) 0;
  327. }
  328. static int
  329. match_disk_config_item(const char *name, conf_disk_item * di_ptr)
  330. {
  331.     int             result = 0;
  332.     size_t          len;
  333.     details_set    *d_set;
  334.     unsigned int    c;
  335.     if (di_ptr) {
  336.         switch (di_ptr->item_type) {
  337.         case ITEM_STRING:
  338.             len = strlen((const char *) di_ptr->item_details);
  339.             if (!strncmp(name, (const char *) di_ptr->item_details, len))
  340.                 result = match_disk_config_item(name + len,
  341.                                                 di_ptr->item_next);
  342.             break;
  343.         case ITEM_SET:
  344.             if (*name) {
  345.                 d_set = (details_set *) di_ptr->item_details;
  346.                 c = ((unsigned int) *name) & 0xff;
  347.                 if ((*d_set)[c / 8] & (unsigned char) (1 << (c % 8)))
  348.                     result = match_disk_config_item(name + 1,
  349.                                                     di_ptr->item_next);
  350.             }
  351.             break;
  352.         case ITEM_STAR:
  353.             if (di_ptr->item_next) {
  354.                 for (; !result && *name; name++)
  355.                     result = match_disk_config_item(name,
  356.                                                     di_ptr->item_next);
  357.             } else {
  358.                 result = 1;
  359.             }
  360.             break;
  361.         case ITEM_ANY:
  362.             if (*name)
  363.                 result = match_disk_config_item(name + 1,
  364.                                                 di_ptr->item_next);
  365.             break;
  366.         }
  367.     } else {
  368.         if (*name == '')
  369.             result = 1;
  370.     }
  371.     return result;
  372. }
  373. static int
  374. match_disk_config(const char *name)
  375. {
  376.     conf_disk_list *d_ptr = conf_list;
  377.     while (d_ptr) {
  378.         if (match_disk_config_item(name, d_ptr->list_item))
  379.             return 1;           /* match found in ignorelist */
  380.         d_ptr = d_ptr->list_next;
  381.     }
  382.     /*
  383.      * no match in ignorelist 
  384.      */
  385.     return 0;
  386. }
  387. /*
  388.  * header_hrdisk(...
  389.  * Arguments:
  390.  * vp     IN      - pointer to variable entry that points here
  391.  * name    IN/OUT  - IN/name requested, OUT/name found
  392.  * length  IN/OUT  - length of IN/OUT oid's 
  393.  * exact   IN      - TRUE if an exact match was requested
  394.  * var_len OUT     - length of variable or 0 if function returned
  395.  * write_method
  396.  */
  397. int
  398. header_hrdisk(struct variable *vp,
  399.               oid * name,
  400.               size_t * length,
  401.               int exact, size_t * var_len, WriteMethod ** write_method)
  402. {
  403. #define HRDISK_ENTRY_NAME_LENGTH 11
  404.     oid             newname[MAX_OID_LEN];
  405.     int             disk_idx, LowIndex = -1;
  406.     int             result;
  407.     DEBUGMSGTL(("host/hr_disk", "var_hrdisk: "));
  408.     DEBUGMSGOID(("host/hr_disk", name, *length));
  409.     DEBUGMSG(("host/hr_disk", " %dn", exact));
  410.     memcpy((char *) newname, (char *) vp->name,
  411.            (int) vp->namelen * sizeof(oid));
  412.     /*
  413.      * Find "next" disk entry 
  414.      */
  415.     Init_HR_Disk();
  416.     for (;;) {
  417.         disk_idx = Get_Next_HR_Disk();
  418.         if (disk_idx == -1)
  419.             break;
  420.         newname[HRDISK_ENTRY_NAME_LENGTH] = disk_idx;
  421.         result =
  422.             snmp_oid_compare(name, *length, newname,
  423.                              (int) vp->namelen + 1);
  424.         if (exact && (result == 0)) {
  425.             LowIndex = disk_idx;
  426.             Save_HR_Disk_Specific();
  427.             break;
  428.         }
  429.         if ((!exact && (result < 0)) &&
  430.             (LowIndex == -1 || disk_idx < LowIndex)) {
  431.             LowIndex = disk_idx;
  432.             Save_HR_Disk_Specific();
  433. #ifdef HRD_MONOTONICALLY_INCREASING
  434.             break;
  435. #endif
  436.         }
  437.     }
  438.     if (LowIndex == -1) {
  439.         DEBUGMSGTL(("host/hr_disk", "... index out of rangen"));
  440.         return (MATCH_FAILED);
  441.     }
  442.     newname[HRDISK_ENTRY_NAME_LENGTH] = LowIndex;
  443.     memcpy((char *) name, (char *) newname,
  444.            ((int) vp->namelen + 1) * sizeof(oid));
  445.     *length = vp->namelen + 1;
  446.     *write_method = 0;
  447.     *var_len = sizeof(long);    /* default to 'long' results */
  448.     DEBUGMSGTL(("host/hr_disk", "... get disk stats "));
  449.     DEBUGMSGOID(("host/hr_disk", name, *length));
  450.     DEBUGMSG(("host/hr_disk", "n"));
  451.     return LowIndex;
  452. }
  453.         /*********************
  454.  *
  455.  *  System specific implementation functions
  456.  *
  457.  *********************/
  458. u_char         *
  459. var_hrdisk(struct variable * vp,
  460.            oid * name,
  461.            size_t * length,
  462.            int exact, size_t * var_len, WriteMethod ** write_method)
  463. {
  464.     int             disk_idx;
  465.     disk_idx =
  466.         header_hrdisk(vp, name, length, exact, var_len, write_method);
  467.     if (disk_idx == MATCH_FAILED)
  468.         return NULL;
  469.     switch (vp->magic) {
  470.     case HRDISK_ACCESS:
  471.         long_return = Is_It_Writeable();
  472.         return (u_char *) & long_return;
  473.     case HRDISK_MEDIA:
  474.         long_return = What_Type_Disk();
  475.         return (u_char *) & long_return;
  476.     case HRDISK_REMOVEABLE:
  477.         long_return = Is_It_Removeable();
  478.         return (u_char *) & long_return;
  479.     case HRDISK_CAPACITY:
  480.         long_return = HRD_savedCapacity;
  481.         return (u_char *) & long_return;
  482.     default:
  483.         DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrdiskn",
  484.                     vp->magic));
  485.     }
  486.     return NULL;
  487. }
  488.         /*********************
  489.  *
  490.  *  Internal implementation functions
  491.  *
  492.  *********************/
  493. #define MAX_NUMBER_DISK_TYPES 16      /* probably should be a variable */
  494. #define MAX_DISKS_PER_TYPE 15      /* SCSI disks - not a hard limit */
  495. #define HRDISK_TYPE_SHIFT 4       /* log2 (MAX_DISKS_PER_TYPE+1) */
  496. typedef struct {
  497.     const char     *disk_devpart_string;        /* printf() format disk part. name */
  498.     short           disk_controller;    /* controller id or -1 if NA */
  499.     short           disk_device_first;  /* first device id */
  500.     short           disk_device_last;   /* last device id */
  501.     const char     *disk_devfull_string;        /* printf() format full disk name */
  502.     short           disk_partition_first;       /* first partition id */
  503.     short           disk_partition_last;        /* last partition id */
  504. } HRD_disk_t;
  505. static HRD_disk_t disk_devices[MAX_NUMBER_DISK_TYPES];
  506. static int      HR_number_disk_types = 0;
  507. static void
  508. Add_HR_Disk_entry(const char *devpart_string,
  509.                   int first_ctl,
  510.                   int last_ctl,
  511.                   int first_dev,
  512.                   int last_dev,
  513.                   const char *devfull_string,
  514.                   int first_partn, int last_partn)
  515. {
  516.     int lodev, hidev, nbr_created = 0;
  517.     while (first_ctl <= last_ctl) {
  518.       for (lodev = first_dev;
  519.            lodev < last_dev && MAX_NUMBER_DISK_TYPES > HR_number_disk_types;
  520.            lodev += (1+MAX_DISKS_PER_TYPE), HR_number_disk_types++)
  521.       {
  522.         nbr_created++;
  523.         /*
  524.          * Split long runs of disks into separate "types"
  525.          */
  526.         hidev = lodev + MAX_DISKS_PER_TYPE;
  527.         if (last_dev < hidev)
  528.             hidev = last_dev;
  529.         disk_devices[HR_number_disk_types].disk_devpart_string =
  530.             devpart_string;
  531.         disk_devices[HR_number_disk_types].disk_controller = first_ctl;
  532.         disk_devices[HR_number_disk_types].disk_device_first = lodev;
  533.         disk_devices[HR_number_disk_types].disk_device_last = hidev;
  534.         disk_devices[HR_number_disk_types].disk_devfull_string =
  535.             devfull_string;
  536.         disk_devices[HR_number_disk_types].disk_partition_first =
  537.             first_partn;
  538.         disk_devices[HR_number_disk_types].disk_partition_last =
  539.             last_partn;
  540. #if DEBUG_TEST
  541.         DEBUGMSGTL(("host/hr_disk",
  542.                     "Add_HR %02d '%s' first=%d last=%dn",
  543.                     HR_number_disk_types, devpart_string, lodev, hidev));
  544. #endif
  545.       }
  546.       first_ctl++;
  547.     }
  548.     if (nbr_created == 0 || MAX_NUMBER_DISK_TYPES < HR_number_disk_types) {
  549.         HR_number_disk_types = MAX_NUMBER_DISK_TYPES;
  550.         DEBUGMSGTL(("host/hr_disk",
  551.                     "WARNING! Add_HR_Disk_entry '%s' incomplete, %d createdn",
  552.                     devpart_string, nbr_created));
  553.     }
  554. #if DEBUG_TEST
  555.     else
  556.         DEBUGMSGTL(("host/hr_disk",
  557.                     "Add_HR_Disk_entry '%s' completed, %d createdn",
  558.                     devpart_string, nbr_created));
  559. #endif
  560. }
  561. void
  562. Init_HR_Disk(void)
  563. {
  564.     HRD_type_index = 0;
  565.     HRD_index = -1;
  566.     DEBUGMSGTL(("host/hr_disk", "Init_Diskn"));
  567. }
  568. int
  569. Get_Next_HR_Disk(void)
  570. {
  571.     char            string[1024];
  572.     int             fd, result;
  573.     int             iindex;
  574.     int             max_disks;
  575.     time_t          now;
  576.     HRD_index++;
  577.     (void *) time(&now);
  578.     DEBUGMSGTL(("host/hr_disk", "Next_Disk type %d of %dn",
  579.                 HRD_type_index, HR_number_disk_types));
  580.     while (HRD_type_index < HR_number_disk_types) {
  581.         max_disks = disk_devices[HRD_type_index].disk_device_last -
  582.             disk_devices[HRD_type_index].disk_device_first + 1;
  583.         DEBUGMSGTL(("host/hr_disk", "Next_Disk max %d of type %dn",
  584.                     max_disks, HRD_type_index));
  585.         while (HRD_index < max_disks) {
  586.             iindex = (HRD_type_index << HRDISK_TYPE_SHIFT) + HRD_index;
  587.             /*
  588.              * Check to see whether this device
  589.              *   has been probed for 'recently'
  590.              *   and skip if so.
  591.              * This has a *major* impact on run
  592.              *   times (by a factor of 10!)
  593.              */
  594.             if ((HRD_history[iindex] > 0) &&
  595.                 ((now - HRD_history[iindex]) < 60)) {
  596.                 HRD_index++;
  597.                 continue;
  598.             }
  599.             /*
  600.              * Construct the full device name in "string" 
  601.              */
  602.             if (disk_devices[HRD_type_index].disk_controller != -1) {
  603.                 snprintf(string, sizeof(string),
  604.                         disk_devices[HRD_type_index].disk_devfull_string,
  605.                         disk_devices[HRD_type_index].disk_controller,
  606.                         disk_devices[HRD_type_index].disk_device_first +
  607.                         HRD_index);
  608.             } else {
  609.                 snprintf(string, sizeof(string),
  610.                         disk_devices[HRD_type_index].disk_devfull_string,
  611.                         disk_devices[HRD_type_index].disk_device_first +
  612.                         HRD_index);
  613.             }
  614.             string[ sizeof(string)-1 ] = 0;
  615.             DEBUGMSGTL(("host/hr_disk", "Get_Next_HR_Disk: %s (%d/%d)n",
  616.                         string, HRD_type_index, HRD_index));
  617.             if (HRD_history[iindex] == -1) {
  618.                 /*
  619.                  * check whether this device is in the "ignoredisk" list in
  620.                  * the config file. if yes this device will be marked as
  621.                  * invalid for the future, i.e. it won't ever be checked
  622.                  * again.
  623.                  */
  624.                 if (match_disk_config(string)) {
  625.                     /*
  626.                      * device name matches entry in ignoredisk list 
  627.                      */
  628.                     DEBUGMSGTL(("host/hr_disk",
  629.                                 "Get_Next_HR_Disk: %s ignoredn", string));
  630.                     HRD_history[iindex] = LONG_MAX;
  631.                     HRD_index++;
  632.                     continue;
  633.                 }
  634.             }
  635.             /*
  636.              * use O_NDELAY to avoid CDROM spin-up and media detection
  637.              * * (too slow) --okir 
  638.              */
  639.             /*
  640.              * at least with HP-UX 11.0 this doesn't seem to work properly
  641.              * * when accessing an empty CDROM device --jsf 
  642.              */
  643. #ifdef O_NDELAY                 /* I'm sure everything has it, but just in case...  --Wes */
  644.             fd = open(string, O_RDONLY | O_NDELAY);
  645. #else
  646.             fd = open(string, O_RDONLY);
  647. #endif
  648.             if (fd != -1) {
  649.                 result = Query_Disk(fd, string);
  650.                 close(fd);
  651.                 if (result != -1) {
  652.                     HRD_history[iindex] = 0;
  653.                     return ((HRDEV_DISK << HRDEV_TYPE_SHIFT) + iindex);
  654.                 }
  655.             }
  656.             HRD_history[iindex] = now;
  657.             HRD_index++;
  658.         }
  659.         HRD_type_index++;
  660.         HRD_index = 0;
  661.     }
  662.     HRD_index = -1;
  663.     return -1;
  664. }
  665. int
  666. Get_Next_HR_Disk_Partition(char *string, size_t str_len, int HRP_index)
  667. {
  668.     DEBUGMSGTL(("host/hr_disk", "Next_Partition type %d/%d:%dn",
  669.                 HRD_type_index, HRD_index, HRP_index));
  670.     /*
  671.      * no more partition names => return -1 
  672.      */
  673.     if (disk_devices[HRD_type_index].disk_partition_last -
  674.         disk_devices[HRD_type_index].disk_partition_first + 1
  675.         <= HRP_index) {
  676.         return -1;
  677.     }
  678.     /*
  679.      * Construct the partition name in "string" 
  680.      */
  681.     if (disk_devices[HRD_type_index].disk_controller != -1) {
  682.         snprintf(string, str_len,
  683.                 disk_devices[HRD_type_index].disk_devpart_string,
  684.                 disk_devices[HRD_type_index].disk_controller,
  685.                 disk_devices[HRD_type_index].disk_device_first + HRD_index,
  686.                 disk_devices[HRD_type_index].disk_partition_first +
  687.                 HRP_index);
  688.     } else {
  689.         snprintf(string, str_len,
  690.                 disk_devices[HRD_type_index].disk_devpart_string,
  691.                 disk_devices[HRD_type_index].disk_device_first + HRD_index,
  692.                 disk_devices[HRD_type_index].disk_partition_first +
  693.                 HRP_index);
  694.     }
  695.     string[ str_len-1 ] = 0;
  696.     DEBUGMSGTL(("host/hr_disk",
  697.                 "Get_Next_HR_Disk_Partition: %s (%d/%d:%d)n", string,
  698.                 HRD_type_index, HRD_index, HRP_index));
  699.     return 0;
  700. }
  701. static void
  702. Save_HR_Disk_Specific(void)
  703. {
  704. #ifdef DIOC_DESCRIBE
  705.     HRD_savedIntf_type = HRD_info.intf_type;
  706.     HRD_savedDev_type = HRD_info.dev_type;
  707.     HRD_savedFlags = HRD_info.flags;
  708.     HRD_savedCapacity = HRD_cap.lba / 2;
  709. #endif
  710. #ifdef DKIOCINFO
  711.     HRD_savedCtrl_type = HRD_info.dki_ctype;
  712.     HRD_savedFlags = HRD_info.dki_flags;
  713.     HRD_savedCapacity = HRD_cap.dkg_ncyl * HRD_cap.dkg_nhead * HRD_cap.dkg_nsect / 2;   /* ??? */
  714. #endif
  715. #ifdef HAVE_LINUX_HDREG_H
  716.     HRD_savedCapacity = HRD_info.lba_capacity / 2;
  717.     HRD_savedFlags = HRD_info.config;
  718. #endif
  719. #ifdef DIOCGDINFO
  720.     HRD_savedCapacity = HRD_info.d_secperunit / 2;
  721. #endif
  722. }
  723. static void
  724. Save_HR_Disk_General(void)
  725. {
  726. #ifdef DIOC_DESCRIBE
  727.     strncpy(HRD_savedModel, HRD_info.model_num, sizeof(HRD_savedModel)-1);
  728.     HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
  729. #endif
  730. #ifdef DKIOCINFO
  731.     strncpy(HRD_savedModel, HRD_info.dki_dname, sizeof(HRD_savedModel)-1);
  732.     HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
  733. #endif
  734. #ifdef HAVE_LINUX_HDREG_H
  735.     strncpy(HRD_savedModel, (const char *) HRD_info.model,
  736.                     sizeof(HRD_savedModel)-1);
  737.     HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
  738. #endif
  739. #ifdef DIOCGDINFO
  740.     strncpy(HRD_savedModel, dktypenames[HRD_info.d_type],
  741.                     sizeof(HRD_savedModel)-1);
  742.     HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
  743. #endif
  744. }
  745. static const char *
  746. describe_disk(int idx)
  747. {
  748.     if (HRD_savedModel[0] == '')
  749.         return ("some sort of disk");
  750.     else
  751.         return (HRD_savedModel);
  752. }
  753. static int
  754. Query_Disk(int fd, const char *devfull)
  755. {
  756.     int             result = -1;
  757. #ifdef DIOC_DESCRIBE
  758.     result = ioctl(fd, DIOC_DESCRIBE, &HRD_info);
  759.     if (result != -1)
  760.         result = ioctl(fd, DIOC_CAPACITY, &HRD_cap);
  761. #endif
  762. #ifdef DKIOCINFO
  763.     result = ioctl(fd, DKIOCINFO, &HRD_info);
  764.     if (result != -1)
  765.         result = ioctl(fd, DKIOCGGEOM, &HRD_cap);
  766. #endif
  767. #ifdef HAVE_LINUX_HDREG_H
  768.     if (HRD_type_index == 0)    /* IDE hard disk */
  769.         result = ioctl(fd, HDIO_GET_IDENTITY, &HRD_info);
  770.     else if (HRD_type_index <= 2) {     /* SCSI hard disk and md devices */
  771.         long            h;
  772.         result = ioctl(fd, BLKGETSIZE, &h);
  773.         if (result != -1 && HRD_type_index == 2 && h == 0L)
  774.             result = -1;        /* ignore empty md devices */
  775.         if (result != -1) {
  776.             HRD_info.lba_capacity = h;
  777.             if (HRD_type_index == 1)
  778.                 snprintf( HRD_info.model, sizeof(HRD_info.model)-1,
  779.                          "SCSI disk (%s)", devfull);
  780.             else
  781.                 snprintf( HRD_info.model, sizeof(HRD_info.model)-1,
  782.                         "RAID disk (%s)", devfull);
  783.             HRD_info.model[ sizeof(HRD_info.model)-1 ] = 0;
  784.             HRD_info.config = 0;
  785.         }
  786.     }
  787. #endif
  788. #ifdef DIOCGDINFO
  789.     result = ioctl(fd, DIOCGDINFO, &HRD_info);
  790. #endif
  791.     return (result);
  792. }
  793. static int
  794. Is_It_Writeable(void)
  795. {
  796. #ifdef DIOC_DESCRIBE
  797.     if ((HRD_savedFlags & WRITE_PROTECT_FLAG) ||
  798.         (HRD_savedDev_type == CDROM_DEV_TYPE))
  799.         return (2);             /* read only */
  800. #endif
  801. #ifdef DKIOCINFO
  802.     if (HRD_savedCtrl_type == DKC_CDROM)
  803.         return (2);             /* read only */
  804. #endif
  805.     return (1);                 /* read-write */
  806. }
  807. static int
  808. What_Type_Disk(void)
  809. {
  810. #ifdef DIOC_DESCRIBE
  811.     switch (HRD_savedDev_type) {
  812.     case DISK_DEV_TYPE:
  813.         if (HRD_savedIntf_type == PC_FDC_INTF)
  814.             return (4);         /* Floppy Disk */
  815.         else
  816.             return (3);         /* Hard Disk */
  817.         break;
  818.     case CDROM_DEV_TYPE:
  819.         return (5);             /* Optical RO */
  820.         break;
  821.     case WORM_DEV_TYPE:
  822.         return (6);             /* Optical WORM */
  823.         break;
  824.     case MO_DEV_TYPE:
  825.         return (7);             /* Optical R/W */
  826.         break;
  827.     default:
  828.         return (2);             /* Unknown */
  829.         break;
  830.     }
  831. #endif
  832. #ifdef DKIOCINFO
  833.     switch (HRD_savedCtrl_type) {
  834.     case DKC_WDC2880:
  835.     case DKC_DSD5215:
  836. #ifdef DKC_XY450
  837.     case DKC_XY450:
  838. #endif
  839.     case DKC_ACB4000:
  840.     case DKC_MD21:
  841. #ifdef DKC_XD7053
  842.     case DKC_XD7053:
  843. #endif
  844.     case DKC_SCSI_CCS:
  845. #ifdef DKC_PANTHER
  846.     case DKC_PANTHER:
  847. #endif
  848. #ifdef DKC_CDC_9057
  849.     case DKC_CDC_9057:
  850. #endif
  851. #ifdef DKC_FJ_M1060
  852.     case DKC_FJ_M1060:
  853. #endif
  854.     case DKC_DIRECT:
  855.     case DKC_PCMCIA_ATA:
  856.         return (3);             /* Hard Disk */
  857.         break;
  858.     case DKC_NCRFLOPPY:
  859.     case DKC_SMSFLOPPY:
  860.     case DKC_INTEL82077:
  861.         return (4);             /* Floppy Disk */
  862.         break;
  863.     case DKC_CDROM:
  864.         return (5);             /* Optical RO */
  865.         break;
  866.     case DKC_PCMCIA_MEM:
  867.         return (8);             /* RAM disk */
  868.         break;
  869.     case DKC_MD:               /* "meta-disk" driver */
  870.         return (1);             /* Other */
  871.         break;
  872.     }
  873. #endif
  874.     return (2);                 /* Unknown */
  875. }
  876. static int
  877. Is_It_Removeable(void)
  878. {
  879. #ifdef DIOC_DESCRIBE
  880.     if ((HRD_savedIntf_type == PC_FDC_INTF) ||
  881.         (HRD_savedDev_type == WORM_DEV_TYPE) ||
  882.         (HRD_savedDev_type == MO_DEV_TYPE) ||
  883.         (HRD_savedDev_type == CDROM_DEV_TYPE))
  884.         return (1);             /* true */
  885. #endif
  886. #ifdef DKIOCINFO
  887.     if ((HRD_savedCtrl_type == DKC_CDROM) ||
  888.         (HRD_savedCtrl_type == DKC_NCRFLOPPY) ||
  889.         (HRD_savedCtrl_type == DKC_SMSFLOPPY) ||
  890.         (HRD_savedCtrl_type == DKC_INTEL82077) ||
  891.         (HRD_savedCtrl_type == DKC_PCMCIA_MEM) ||
  892.         (HRD_savedCtrl_type == DKC_PCMCIA_ATA))
  893.         return (1);             /* true */
  894. #endif
  895. #ifdef HAVE_LINUX_HDREG_H
  896.     if (HRD_savedFlags & 0x80)
  897.         return (1);             /* true */
  898. #endif
  899.     return (2);                 /* false */
  900. }