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 *, size_t, 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, size_t str_len, 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, str_len,
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, str_len,
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[ str_len-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 */