2 * Host Resources MIB - disk device group implementation - hr_disk.c
6 #include <net-snmp/net-snmp-config.h>
25 # define dirent direct
27 # include <sys/ndir.h>
37 #include <sys/ioctl.h>
43 #if HAVE_SYS_DISKIO_H /* HP-UX only ? */
44 #include <sys/diskio.h>
46 #if HAVE_LINUX_HDREG_H
47 #include <linux/hdreg.h>
49 #if HAVE_SYS_DISKLABEL_H
51 #include <sys/disklabel.h>
53 #if TIME_WITH_SYS_TIME
54 # include <sys/time.h>
58 # include <sys/time.h>
70 * define BLKGETSIZE from <linux/fs.h>:
71 * Note: cannot include this file completely due to errors with redefinition
72 * of structures (at least with older linux versions) --jsf
74 #define BLKGETSIZE _IO(0x12,96) /* return device size */
77 #include <net-snmp/agent/agent_read_config.h>
78 #include <net-snmp/library/read_config.h>
80 #define HRD_MONOTONICALLY_INCREASING
82 /*********************
84 * Kernel & interface information,
85 * and internal forward declarations
87 *********************/
89 void Init_HR_Disk(void);
90 int Get_Next_HR_Disk(void);
91 int Get_Next_HR_Disk_Partition(char *, int);
92 static void Add_HR_Disk_entry(const char *, int, int, int, int,
93 const char *, int, int);
94 static void Save_HR_Disk_General(void);
95 static void Save_HR_Disk_Specific(void);
96 static int Query_Disk(int, const char *);
97 static int Is_It_Writeable(void);
98 static int What_Type_Disk(void);
99 static int Is_It_Removeable(void);
100 static const char *describe_disk(int);
102 int header_hrdisk(struct variable *, oid *, size_t *, int,
103 size_t *, WriteMethod **);
105 static int HRD_type_index;
106 static int HRD_index;
107 static char HRD_savedModel[40];
108 static long HRD_savedCapacity = 1044;
109 static int HRD_savedFlags;
110 static time_t HRD_history[HRDEV_TYPE_MASK];
113 static disk_describe_type HRD_info;
114 static capacity_type HRD_cap;
116 static int HRD_savedIntf_type;
117 static int HRD_savedDev_type;
121 static struct dk_cinfo HRD_info;
122 static struct dk_geom HRD_cap;
124 static int HRD_savedCtrl_type;
127 #ifdef HAVE_LINUX_HDREG_H
128 static struct hd_driveid HRD_info;
132 static struct disklabel HRD_info;
135 static void parse_disk_config(const char *, char *);
136 static void free_disk_config(void);
138 /*********************
140 * Initialisation & common implementation functions
142 *********************/
144 #define HRDISK_ACCESS 1
145 #define HRDISK_MEDIA 2
146 #define HRDISK_REMOVEABLE 3
147 #define HRDISK_CAPACITY 4
149 struct variable4 hrdisk_variables[] = {
150 {HRDISK_ACCESS, ASN_INTEGER, RONLY, var_hrdisk, 2, {1, 1}},
151 {HRDISK_MEDIA, ASN_INTEGER, RONLY, var_hrdisk, 2, {1, 2}},
152 {HRDISK_REMOVEABLE, ASN_INTEGER, RONLY, var_hrdisk, 2, {1, 3}},
153 {HRDISK_CAPACITY, ASN_INTEGER, RONLY, var_hrdisk, 2, {1, 4}}
155 oid hrdisk_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 3, 6 };
163 init_device[HRDEV_DISK] = Init_HR_Disk;
164 next_device[HRDEV_DISK] = Get_Next_HR_Disk;
165 save_device[HRDEV_DISK] = Save_HR_Disk_General;
166 #ifdef HRD_MONOTONICALLY_INCREASING
167 dev_idx_inc[HRDEV_DISK] = 1;
171 Add_HR_Disk_entry("/dev/hd%c%d", -1, -1, 'a', 'l', "/dev/hd%c", 1, 15);
172 Add_HR_Disk_entry("/dev/sd%c%d", -1, -1, 'a', 'p', "/dev/sd%c", 1, 15);
173 Add_HR_Disk_entry("/dev/md%d", -1, -1, 0, 3, "/dev/md%d", 0, 0);
174 Add_HR_Disk_entry("/dev/fd%d", -1, -1, 0, 1, "/dev/fd%d", 0, 0);
176 #if defined(hpux10) || defined(hpux11)
177 Add_HR_Disk_entry("/dev/rdsk/c%dt%xd%d", 0, 1, 0, 15,
178 "/dev/rdsk/c%dt%xd0", 0, 4);
180 Add_HR_Disk_entry("/dev/rdsk/c%dd%xs%d", 201, 201, 0, 15,
181 "/dev/rdsk/c%dd%xs0", 0, 4);
183 #elif defined(solaris2)
184 Add_HR_Disk_entry("/dev/rdsk/c%dt%dd0s%d", 0, 1, 0, 15,
185 "/dev/rdsk/c%dt%dd0s0", 0, 7);
186 Add_HR_Disk_entry("/dev/rdsk/c%dd%ds%d", 0, 1, 0, 15,
187 "/dev/rdsk/c%dd%ds0", 0, 7);
188 #elif defined(freebsd4) || defined(freebsd5)
189 Add_HR_Disk_entry("/dev/ad%ds%d%c", 0, 1, 1, 4, "/dev/ad%ds%d", 'a', 'h');
190 Add_HR_Disk_entry("/dev/da%ds%d%c", 0, 1, 1, 4, "/dev/da%ds%d", 'a', 'h');
191 #elif defined(freebsd3)
192 Add_HR_Disk_entry("/dev/wd%ds%d%c", 0, 1, 1, 4, "/dev/wd%ds%d", 'a',
194 Add_HR_Disk_entry("/dev/sd%ds%d%c", 0, 1, 1, 4, "/dev/sd%ds%d", 'a',
196 #elif defined(freebsd2)
197 Add_HR_Disk_entry("/dev/wd%d%c", -1, -1, 0, 3, "/dev/wd%d", 'a', 'h');
198 Add_HR_Disk_entry("/dev/sd%d%c", -1, -1, 0, 3, "/dev/sd%d", 'a', 'h');
199 #elif defined(netbsd1)
200 Add_HR_Disk_entry("/dev/wd%d%c", -1, -1, 0, 3, "/dev/wd%dc", 'a', 'h');
201 Add_HR_Disk_entry("/dev/sd%d%c", -1, -1, 0, 3, "/dev/sd%dc", 'a', 'h');
204 device_descr[HRDEV_DISK] = describe_disk;
205 HRD_savedModel[0] = '\0';
206 HRD_savedCapacity = 0;
208 for (i = 0; i < HRDEV_TYPE_MASK; ++i)
211 REGISTER_MIB("host/hr_disk", hrdisk_variables, variable4,
212 hrdisk_variables_oid);
214 snmpd_register_config_handler("ignoredisk", parse_disk_config,
215 free_disk_config, "name");
218 #define ITEM_STRING 1
223 typedef unsigned char details_set[32];
225 typedef struct _conf_disk_item {
226 int item_type; /* ITEM_STRING, ITEM_SET, ITEM_STAR, ITEM_ANY */
227 void *item_details; /* content depends upon item_type */
228 struct _conf_disk_item *item_next;
231 typedef struct _conf_disk_list {
232 conf_disk_item *list_item;
233 struct _conf_disk_list *list_next;
235 static conf_disk_list *conf_list;
237 static int match_disk_config(const char *);
238 static int match_disk_config_item(const char *, conf_disk_item *);
241 parse_disk_config(const char *token, char *cptr)
243 conf_disk_list *d_new;
244 conf_disk_item *di_curr;
246 char *name, *p, *d_str, c;
247 unsigned int i, neg, c1, c2;
249 name = strtok(cptr, " \t");
251 config_perror("Missing NAME parameter");
254 d_new = (conf_disk_list *) malloc(sizeof(conf_disk_list));
256 config_perror("Out of memory");
259 di_curr = (conf_disk_item *) malloc(sizeof(conf_disk_item));
261 config_perror("Out of memory");
264 d_new->list_item = di_curr;
267 di_curr->item_type = ITEM_ANY;
268 di_curr->item_details = (void *) 0;
270 } else if (*name == '*') {
271 di_curr->item_type = ITEM_STAR;
272 di_curr->item_details = (void *) 0;
274 } else if (*name == '[') {
275 d_set = (details_set *) malloc(sizeof(details_set));
277 config_perror("Out of memory");
280 for (i = 0; i < sizeof(details_set); i++)
281 (*d_set)[i] = (unsigned char) 0;
283 if (*name == '^' || *name == '!') {
289 while (*name && *name != ']') {
290 c1 = ((unsigned int) *name++) & 0xff;
291 if (*name == '-' && *(name + 1) != ']') {
293 c2 = ((unsigned int) *name++) & 0xff;
297 for (i = c1; i <= c2; i++)
298 (*d_set)[i / 8] |= (unsigned char) (1 << (i % 8));
302 ("Syntax error in NAME: invalid set specified");
306 for (i = 0; i < sizeof(details_set); i++)
307 (*d_set)[i] = (*d_set)[i] ^ (unsigned char) 0xff;
309 di_curr->item_type = ITEM_SET;
310 di_curr->item_details = (void *) d_set;
314 *p != '\0' && *p != '?' && *p != '*' && *p != '['; p++);
317 d_str = (char *) malloc(strlen(name) + 1);
319 config_perror("Out of memory");
324 di_curr->item_type = ITEM_STRING;
325 di_curr->item_details = (void *) d_str;
329 di_curr->item_next = (conf_disk_item *) 0;
333 (conf_disk_item *) malloc(sizeof(conf_disk_item));
334 if (!di_curr->item_next) {
335 config_perror("Out of memory");
338 di_curr = di_curr->item_next;
340 d_new->list_next = conf_list;
345 free_disk_config(void)
347 conf_disk_list *d_ptr = conf_list, *d_next;
348 conf_disk_item *di_ptr, *di_next;
351 d_next = d_ptr->list_next;
352 di_ptr = d_ptr->list_item;
354 di_next = di_ptr->item_next;
355 if (di_ptr->item_details)
356 free(di_ptr->item_details);
357 free((void *) di_ptr);
360 free((void *) d_ptr);
363 conf_list = (conf_disk_list *) 0;
367 match_disk_config_item(const char *name, conf_disk_item * di_ptr)
375 switch (di_ptr->item_type) {
377 len = strlen((const char *) di_ptr->item_details);
378 if (!strncmp(name, (const char *) di_ptr->item_details, len))
379 result = match_disk_config_item(name + len,
384 d_set = (details_set *) di_ptr->item_details;
385 c = ((unsigned int) *name) & 0xff;
386 if ((*d_set)[c / 8] & (unsigned char) (1 << (c % 8)))
387 result = match_disk_config_item(name + 1,
392 if (di_ptr->item_next) {
393 for (; !result && *name; name++)
394 result = match_disk_config_item(name,
402 result = match_disk_config_item(name + 1,
415 match_disk_config(const char *name)
417 conf_disk_list *d_ptr = conf_list;
420 if (match_disk_config_item(name, d_ptr->list_item))
421 return 1; /* match found in ignorelist */
422 d_ptr = d_ptr->list_next;
426 * no match in ignorelist
434 * vp IN - pointer to variable entry that points here
435 * name IN/OUT - IN/name requested, OUT/name found
436 * length IN/OUT - length of IN/OUT oid's
437 * exact IN - TRUE if an exact match was requested
438 * var_len OUT - length of variable or 0 if function returned
443 header_hrdisk(struct variable *vp,
446 int exact, size_t * var_len, WriteMethod ** write_method)
448 #define HRDISK_ENTRY_NAME_LENGTH 11
449 oid newname[MAX_OID_LEN];
450 int disk_idx, LowIndex = -1;
453 DEBUGMSGTL(("host/hr_disk", "var_hrdisk: "));
454 DEBUGMSGOID(("host/hr_disk", name, *length));
455 DEBUGMSG(("host/hr_disk", " %d\n", exact));
457 memcpy((char *) newname, (char *) vp->name,
458 (int) vp->namelen * sizeof(oid));
460 * Find "next" disk entry
465 disk_idx = Get_Next_HR_Disk();
468 newname[HRDISK_ENTRY_NAME_LENGTH] = disk_idx;
470 snmp_oid_compare(name, *length, newname,
471 (int) vp->namelen + 1);
472 if (exact && (result == 0)) {
474 Save_HR_Disk_Specific();
477 if ((!exact && (result < 0)) &&
478 (LowIndex == -1 || disk_idx < LowIndex)) {
480 Save_HR_Disk_Specific();
481 #ifdef HRD_MONOTONICALLY_INCREASING
487 if (LowIndex == -1) {
488 DEBUGMSGTL(("host/hr_disk", "... index out of range\n"));
489 return (MATCH_FAILED);
492 newname[HRDISK_ENTRY_NAME_LENGTH] = LowIndex;
493 memcpy((char *) name, (char *) newname,
494 ((int) vp->namelen + 1) * sizeof(oid));
495 *length = vp->namelen + 1;
497 *var_len = sizeof(long); /* default to 'long' results */
499 DEBUGMSGTL(("host/hr_disk", "... get disk stats "));
500 DEBUGMSGOID(("host/hr_disk", name, *length));
501 DEBUGMSG(("host/hr_disk", "\n"));
507 /*********************
509 * System specific implementation functions
511 *********************/
515 var_hrdisk(struct variable * vp,
518 int exact, size_t * var_len, WriteMethod ** write_method)
523 header_hrdisk(vp, name, length, exact, var_len, write_method);
524 if (disk_idx == MATCH_FAILED)
530 long_return = Is_It_Writeable();
531 return (u_char *) & long_return;
533 long_return = What_Type_Disk();
534 return (u_char *) & long_return;
535 case HRDISK_REMOVEABLE:
536 long_return = Is_It_Removeable();
537 return (u_char *) & long_return;
538 case HRDISK_CAPACITY:
539 long_return = HRD_savedCapacity;
540 return (u_char *) & long_return;
542 DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrdisk\n",
549 /*********************
551 * Internal implementation functions
553 *********************/
555 #define MAX_NUMBER_DISK_TYPES 16 /* probably should be a variable */
556 #define MAX_DISKS_PER_TYPE 15 /* SCSI disks - not a hard limit */
557 #define HRDISK_TYPE_SHIFT 4 /* log2 (MAX_DISKS_PER_TYPE+1) */
560 const char *disk_devpart_string; /* printf() format disk part. name */
561 short disk_controller; /* controller id or -1 if NA */
562 short disk_device_first; /* first device id */
563 short disk_device_last; /* last device id */
564 const char *disk_devfull_string; /* printf() format full disk name */
565 short disk_partition_first; /* first partition id */
566 short disk_partition_last; /* last partition id */
569 static HRD_disk_t disk_devices[MAX_NUMBER_DISK_TYPES];
570 static int HR_number_disk_types = 0;
573 Add_HR_Disk_entry(const char *devpart_string,
578 const char *devfull_string,
579 int first_partn, int last_partn)
581 while (first_ctl <= last_ctl) {
582 disk_devices[HR_number_disk_types].disk_devpart_string =
584 disk_devices[HR_number_disk_types].disk_controller = first_ctl;
585 disk_devices[HR_number_disk_types].disk_device_first = first_dev;
586 disk_devices[HR_number_disk_types].disk_device_last = last_dev;
587 disk_devices[HR_number_disk_types].disk_devfull_string =
589 disk_devices[HR_number_disk_types].disk_partition_first =
591 disk_devices[HR_number_disk_types].disk_partition_last =
595 * Split long runs of disks into separate "types"
597 while (last_dev - first_dev > MAX_DISKS_PER_TYPE) {
598 first_dev = first_dev + MAX_DISKS_PER_TYPE;
599 disk_devices[HR_number_disk_types].disk_device_last =
601 HR_number_disk_types++;
603 disk_devices[HR_number_disk_types].disk_devpart_string =
605 disk_devices[HR_number_disk_types].disk_controller = first_ctl;
606 disk_devices[HR_number_disk_types].disk_device_first =
608 disk_devices[HR_number_disk_types].disk_device_last = last_dev;
609 disk_devices[HR_number_disk_types].disk_devfull_string =
611 disk_devices[HR_number_disk_types].disk_partition_first =
613 disk_devices[HR_number_disk_types].disk_partition_last =
618 HR_number_disk_types++;
627 DEBUGMSGTL(("host/hr_disk", "Init_Disk\n"));
631 Get_Next_HR_Disk(void)
641 DEBUGMSGTL(("host/hr_disk", "Next_Disk type %d of %d\n",
642 HRD_type_index, HR_number_disk_types));
643 while (HRD_type_index < HR_number_disk_types) {
644 max_disks = disk_devices[HRD_type_index].disk_device_last -
645 disk_devices[HRD_type_index].disk_device_first + 1;
646 DEBUGMSGTL(("host/hr_disk", "Next_Disk max %d of type %d\n",
647 max_disks, HRD_type_index));
649 while (HRD_index < max_disks) {
650 iindex = (HRD_type_index << HRDISK_TYPE_SHIFT) + HRD_index;
653 * Check to see whether this device
654 * has been probed for 'recently'
656 * This has a *major* impact on run
657 * times (by a factor of 10!)
659 if ((HRD_history[iindex] > 0) &&
660 ((now - HRD_history[iindex]) < 60)) {
666 * Construct the full device name in "string"
668 if (disk_devices[HRD_type_index].disk_controller != -1) {
669 snprintf(string, sizeof(string),
670 disk_devices[HRD_type_index].disk_devfull_string,
671 disk_devices[HRD_type_index].disk_controller,
672 disk_devices[HRD_type_index].disk_device_first +
675 snprintf(string, sizeof(string),
676 disk_devices[HRD_type_index].disk_devfull_string,
677 disk_devices[HRD_type_index].disk_device_first +
680 string[ sizeof(string)-1 ] = 0;
682 DEBUGMSGTL(("host/hr_disk", "Get_Next_HR_Disk: %s (%d/%d)\n",
683 string, HRD_type_index, HRD_index));
685 if (HRD_history[iindex] == -1) {
687 * check whether this device is in the "ignoredisk" list in
688 * the config file. if yes this device will be marked as
689 * invalid for the future, i.e. it won't ever be checked
692 if (match_disk_config(string)) {
694 * device name matches entry in ignoredisk list
696 DEBUGMSGTL(("host/hr_disk",
697 "Get_Next_HR_Disk: %s ignored\n", string));
698 HRD_history[iindex] = LONG_MAX;
705 * use O_NDELAY to avoid CDROM spin-up and media detection
706 * * (too slow) --okir
709 * at least with HP-UX 11.0 this doesn't seem to work properly
710 * * when accessing an empty CDROM device --jsf
712 #ifdef O_NDELAY /* I'm sure everything has it, but just in case... --Wes */
713 fd = open(string, O_RDONLY | O_NDELAY);
715 fd = open(string, O_RDONLY);
718 result = Query_Disk(fd, string);
721 HRD_history[iindex] = 0;
722 return ((HRDEV_DISK << HRDEV_TYPE_SHIFT) + iindex);
725 HRD_history[iindex] = now;
736 Get_Next_HR_Disk_Partition(char *string, int HRP_index)
738 DEBUGMSGTL(("host/hr_disk", "Next_Partition type %d/%d:%d\n",
739 HRD_type_index, HRD_type_index, HRP_index));
742 * no more partition names => return -1
744 if (disk_devices[HRD_type_index].disk_partition_last -
745 disk_devices[HRD_type_index].disk_partition_first + 1
751 * Construct the partition name in "string"
753 if (disk_devices[HRD_type_index].disk_controller != -1) {
754 snprintf(string, sizeof(string),
755 disk_devices[HRD_type_index].disk_devpart_string,
756 disk_devices[HRD_type_index].disk_controller,
757 disk_devices[HRD_type_index].disk_device_first + HRD_index,
758 disk_devices[HRD_type_index].disk_partition_first +
761 snprintf(string, sizeof(string),
762 disk_devices[HRD_type_index].disk_devpart_string,
763 disk_devices[HRD_type_index].disk_device_first + HRD_index,
764 disk_devices[HRD_type_index].disk_partition_first +
767 string[ sizeof(string)-1 ] = 0;
769 DEBUGMSGTL(("host/hr_disk",
770 "Get_Next_HR_Disk_Partition: %s (%d/%d:%d)\n", string,
771 HRD_type_index, HRD_index, HRP_index));
777 Save_HR_Disk_Specific(void)
780 HRD_savedIntf_type = HRD_info.intf_type;
781 HRD_savedDev_type = HRD_info.dev_type;
782 HRD_savedFlags = HRD_info.flags;
783 HRD_savedCapacity = HRD_cap.lba / 2;
786 HRD_savedCtrl_type = HRD_info.dki_ctype;
787 HRD_savedFlags = HRD_info.dki_flags;
788 HRD_savedCapacity = HRD_cap.dkg_ncyl * HRD_cap.dkg_nhead * HRD_cap.dkg_nsect / 2; /* ??? */
790 #ifdef HAVE_LINUX_HDREG_H
791 HRD_savedCapacity = HRD_info.lba_capacity / 2;
792 HRD_savedFlags = HRD_info.config;
795 HRD_savedCapacity = HRD_info.d_secperunit / 2;
800 Save_HR_Disk_General(void)
803 strncpy(HRD_savedModel, HRD_info.model_num, sizeof(HRD_savedModel)-1);
804 HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
807 strncpy(HRD_savedModel, HRD_info.dki_dname, sizeof(HRD_savedModel)-1);
808 HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
810 #ifdef HAVE_LINUX_HDREG_H
811 strncpy(HRD_savedModel, (const char *) HRD_info.model,
812 sizeof(HRD_savedModel)-1);
813 HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
816 strncpy(HRD_savedModel, dktypenames[HRD_info.d_type],
817 sizeof(HRD_savedModel)-1);
818 HRD_savedModel[ sizeof(HRD_savedModel)-1 ] = 0;
823 describe_disk(int idx)
825 if (HRD_savedModel[0] == '\0')
826 return ("some sort of disk");
828 return (HRD_savedModel);
833 Query_Disk(int fd, const char *devfull)
838 result = ioctl(fd, DIOC_DESCRIBE, &HRD_info);
840 result = ioctl(fd, DIOC_CAPACITY, &HRD_cap);
844 result = ioctl(fd, DKIOCINFO, &HRD_info);
846 result = ioctl(fd, DKIOCGGEOM, &HRD_cap);
849 #ifdef HAVE_LINUX_HDREG_H
850 if (HRD_type_index == 0) /* IDE hard disk */
851 result = ioctl(fd, HDIO_GET_IDENTITY, &HRD_info);
852 else if (HRD_type_index <= 2) { /* SCSI hard disk and md devices */
854 result = ioctl(fd, BLKGETSIZE, &h);
855 if (result != -1 && HRD_type_index == 2 && h == 0L)
856 result = -1; /* ignore empty md devices */
858 HRD_info.lba_capacity = h;
859 if (HRD_type_index == 1)
860 snprintf( HRD_info.model, sizeof(HRD_info.model)-1,
861 "SCSI disk (%s)", devfull);
863 snprintf( HRD_info.model, sizeof(HRD_info.model)-1,
864 "RAID disk (%s)", devfull);
865 HRD_info.model[ sizeof(HRD_info.model)-1 ] = 0;
872 result = ioctl(fd, DIOCGDINFO, &HRD_info);
880 Is_It_Writeable(void)
883 if ((HRD_savedFlags & WRITE_PROTECT_FLAG) ||
884 (HRD_savedDev_type == CDROM_DEV_TYPE))
885 return (2); /* read only */
889 if (HRD_savedCtrl_type == DKC_CDROM)
890 return (2); /* read only */
893 return (1); /* read-write */
900 switch (HRD_savedDev_type) {
902 if (HRD_savedIntf_type == PC_FDC_INTF)
903 return (4); /* Floppy Disk */
905 return (3); /* Hard Disk */
908 return (5); /* Optical RO */
911 return (6); /* Optical WORM */
914 return (7); /* Optical R/W */
917 return (2); /* Unknown */
923 switch (HRD_savedCtrl_type) {
946 return (3); /* Hard Disk */
951 return (4); /* Floppy Disk */
954 return (5); /* Optical RO */
957 return (8); /* RAM disk */
959 case DKC_MD: /* "meta-disk" driver */
960 return (1); /* Other */
966 return (2); /* Unknown */
970 Is_It_Removeable(void)
973 if ((HRD_savedIntf_type == PC_FDC_INTF) ||
974 (HRD_savedDev_type == WORM_DEV_TYPE) ||
975 (HRD_savedDev_type == MO_DEV_TYPE) ||
976 (HRD_savedDev_type == CDROM_DEV_TYPE))
977 return (1); /* true */
981 if ((HRD_savedCtrl_type == DKC_CDROM) ||
982 (HRD_savedCtrl_type == DKC_NCRFLOPPY) ||
983 (HRD_savedCtrl_type == DKC_SMSFLOPPY) ||
984 (HRD_savedCtrl_type == DKC_INTEL82077) ||
985 (HRD_savedCtrl_type == DKC_PCMCIA_MEM) ||
986 (HRD_savedCtrl_type == DKC_PCMCIA_ATA))
987 return (1); /* true */
990 #ifdef HAVE_LINUX_HDREG_H
991 if (HRD_savedFlags & 0x80)
992 return (1); /* true */
995 return (2); /* false */