|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Host Resources MIB - disk device group implementation - hr_disk.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 "host_res.h"
|
|
Packit |
fcad23 |
#include "hr_disk.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 |
|
|
Packit |
fcad23 |
#include <fcntl.h>
|
|
Packit |
fcad23 |
#if HAVE_UNISTD_H
|
|
Packit |
fcad23 |
#include <unistd.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_KVM_H
|
|
Packit |
fcad23 |
#include <kvm.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_DIRENT_H
|
|
Packit |
fcad23 |
#include <dirent.h>
|
|
Packit |
fcad23 |
#else
|
|
Packit |
fcad23 |
# define dirent direct
|
|
Packit |
fcad23 |
# if HAVE_SYS_NDIR_H
|
|
Packit |
fcad23 |
# include <sys/ndir.h>
|
|
Packit |
fcad23 |
# endif
|
|
Packit |
fcad23 |
# if HAVE_SYS_DIR_H
|
|
Packit |
fcad23 |
# include <sys/dir.h>
|
|
Packit |
fcad23 |
# endif
|
|
Packit |
fcad23 |
# if HAVE_NDIR_H
|
|
Packit |
fcad23 |
# include <ndir.h>
|
|
Packit |
fcad23 |
# endif
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_SYS_IOCTL_H
|
|
Packit |
fcad23 |
#include <sys/ioctl.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#if HAVE_SYS_DKIO_H
|
|
Packit |
fcad23 |
#include <sys/dkio.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_SYS_DISKIO_H /* HP-UX only ? */
|
|
Packit |
fcad23 |
#include <sys/diskio.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_LINUX_HDREG_H
|
|
Packit |
fcad23 |
#include <linux/hdreg.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if HAVE_SYS_DISKLABEL_H
|
|
Packit |
fcad23 |
#define DKTYPENAMES
|
|
Packit |
fcad23 |
#include <sys/disklabel.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#if TIME_WITH_SYS_TIME
|
|
Packit |
fcad23 |
# include <sys/time.h>
|
|
Packit |
fcad23 |
# include <time.h>
|
|
Packit |
fcad23 |
#else
|
|
Packit |
fcad23 |
# if HAVE_SYS_TIME_H
|
|
Packit |
fcad23 |
# include <sys/time.h>
|
|
Packit |
fcad23 |
# else
|
|
Packit |
fcad23 |
# include <time.h>
|
|
Packit |
fcad23 |
# endif
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP)
|
|
Packit |
fcad23 |
#include <regex.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#if HAVE_LIMITS_H
|
|
Packit |
fcad23 |
#include <limits.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef darwin
|
|
Packit |
fcad23 |
#include <CoreFoundation/CoreFoundation.h>
|
|
Packit |
fcad23 |
#include <IOKit/IOKitLib.h>
|
|
Packit |
fcad23 |
#include <IOKit/storage/IOBlockStorageDriver.h>
|
|
Packit |
fcad23 |
#include <IOKit/storage/IOMedia.h>
|
|
Packit |
fcad23 |
#include <IOKit/IOBSD.h>
|
|
Packit |
fcad23 |
#include <DiskArbitration/DADisk.h>
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef linux
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* define BLKGETSIZE from <linux/fs.h>:
|
|
Packit |
fcad23 |
* Note: cannot include this file completely due to errors with redefinition
|
|
Packit |
fcad23 |
* of structures (at least with older linux versions) --jsf
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
#define BLKGETSIZE _IO(0x12,96) /* return device size */
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#include <net-snmp/agent/agent_read_config.h>
|
|
Packit |
fcad23 |
#include <net-snmp/library/read_config.h>
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#define HRD_MONOTONICALLY_INCREASING
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*************************************************************
|
|
Packit |
fcad23 |
* constants for enums for the MIB node
|
|
Packit |
fcad23 |
* hrDiskStorageAccess (INTEGER / ASN_INTEGER)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
#define HRDISKSTORAGEACCESS_READWRITE 1
|
|
Packit |
fcad23 |
#define HRDISKSTORAGEACCESS_READONLY 2
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*************************************************************
|
|
Packit |
fcad23 |
* constants for enums for the MIB node
|
|
Packit |
fcad23 |
* hrDiskStorageMedia (INTEGER / ASN_INTEGER)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
#define HRDISKSTORAGEMEDIA_OTHER 1
|
|
Packit |
fcad23 |
#define HRDISKSTORAGEMEDIA_UNKNOWN 2
|
|
Packit |
fcad23 |
#define HRDISKSTORAGEMEDIA_HARDDISK 3
|
|
Packit |
fcad23 |
#define HRDISKSTORAGEMEDIA_FLOPPYDISK 4
|
|
Packit |
fcad23 |
#define HRDISKSTORAGEMEDIA_OPTICALDISKROM 5
|
|
Packit |
fcad23 |
#define HRDISKSTORAGEMEDIA_OPTICALDISKWORM 6
|
|
Packit |
fcad23 |
#define HRDISKSTORAGEMEDIA_OPTICALDISKRW 7
|
|
Packit |
fcad23 |
#define HRDISKSTORAGEMEDIA_RAMDISK 8
|
|
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 |
#if !(defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7))
|
|
Packit |
fcad23 |
static void Add_HR_Disk_entry(const char *, int, int, int, int,
|
|
Packit |
fcad23 |
const char *, int, int);
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
static void Save_HR_Disk_General(void);
|
|
Packit |
fcad23 |
static void Save_HR_Disk_Specific(void);
|
|
Packit |
fcad23 |
static int Query_Disk(int, const char *);
|
|
Packit |
fcad23 |
static int Is_It_Writeable(void);
|
|
Packit |
fcad23 |
static int What_Type_Disk(void);
|
|
Packit |
fcad23 |
static int Is_It_Removeable(void);
|
|
Packit |
fcad23 |
static const char *describe_disk(int);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int header_hrdisk(struct variable *, oid *, size_t *, int,
|
|
Packit |
fcad23 |
size_t *, WriteMethod **);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int HRD_type_index;
|
|
Packit |
fcad23 |
static int HRD_index;
|
|
Packit |
fcad23 |
static char HRD_savedModel[40];
|
|
Packit |
fcad23 |
static long HRD_savedCapacity = 1044;
|
|
Packit |
fcad23 |
#if defined(DIOC_DESCRIBE) || defined(DKIOCINFO) || defined(HAVE_LINUX_HDREG_H)
|
|
Packit |
fcad23 |
static int HRD_savedFlags;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
static time_t HRD_history[HRDEV_TYPE_MASK + 1];
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef DIOC_DESCRIBE
|
|
Packit |
fcad23 |
static disk_describe_type HRD_info;
|
|
Packit |
fcad23 |
static capacity_type HRD_cap;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int HRD_savedIntf_type;
|
|
Packit |
fcad23 |
static int HRD_savedDev_type;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef DKIOCINFO
|
|
Packit |
fcad23 |
static struct dk_cinfo HRD_info;
|
|
Packit |
fcad23 |
static struct dk_geom HRD_cap;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int HRD_savedCtrl_type;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef HAVE_LINUX_HDREG_H
|
|
Packit |
fcad23 |
static struct hd_driveid HRD_info;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef DIOCGDINFO
|
|
Packit |
fcad23 |
static struct disklabel HRD_info;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef darwin
|
|
Packit |
fcad23 |
static int64_t HRD_cap;
|
|
Packit |
fcad23 |
static int HRD_access;
|
|
Packit |
fcad23 |
static int HRD_type;
|
|
Packit |
fcad23 |
static int HRD_removeble;
|
|
Packit |
fcad23 |
static char HRD_model[40];
|
|
Packit |
fcad23 |
static int HRD_saved_access;
|
|
Packit |
fcad23 |
static int HRD_saved_type;
|
|
Packit |
fcad23 |
static int HRD_saved_removeble;
|
|
Packit |
fcad23 |
static int _get_type_from_protocol( const char *prot );
|
|
Packit |
fcad23 |
static int _get_type_value( const char *str_type );
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static void parse_disk_config(const char *, char *);
|
|
Packit |
fcad23 |
static void free_disk_config(void);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef linux
|
|
Packit |
fcad23 |
static void Add_LVM_Disks(void);
|
|
Packit |
fcad23 |
static void Remove_LVM_Disks(void);
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*********************
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
* Initialisation & common implementation functions
|
|
Packit |
fcad23 |
*
|
|
Packit |
fcad23 |
*********************/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#define HRDISK_ACCESS 1
|
|
Packit |
fcad23 |
#define HRDISK_MEDIA 2
|
|
Packit |
fcad23 |
#define HRDISK_REMOVEABLE 3
|
|
Packit |
fcad23 |
#define HRDISK_CAPACITY 4
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
struct variable4 hrdisk_variables[] = {
|
|
Packit |
fcad23 |
{HRDISK_ACCESS, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
|
|
Packit |
fcad23 |
var_hrdisk, 2, {1, 1}},
|
|
Packit |
fcad23 |
{HRDISK_MEDIA, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
|
|
Packit |
fcad23 |
var_hrdisk, 2, {1, 2}},
|
|
Packit |
fcad23 |
{HRDISK_REMOVEABLE, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
|
|
Packit |
fcad23 |
var_hrdisk, 2, {1, 3}},
|
|
Packit |
fcad23 |
{HRDISK_CAPACITY, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
|
|
Packit |
fcad23 |
var_hrdisk, 2, {1, 4}}
|
|
Packit |
fcad23 |
};
|
|
Packit |
fcad23 |
oid hrdisk_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 3, 6 };
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
init_hr_disk(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int i;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
init_device[HRDEV_DISK] = Init_HR_Disk;
|
|
Packit |
fcad23 |
next_device[HRDEV_DISK] = Get_Next_HR_Disk;
|
|
Packit |
fcad23 |
save_device[HRDEV_DISK] = Save_HR_Disk_General;
|
|
Packit |
fcad23 |
#ifdef HRD_MONOTONICALLY_INCREASING
|
|
Packit |
fcad23 |
dev_idx_inc[HRDEV_DISK] = 1;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#if defined(linux)
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/hd%c%d", -1, -1, 'a', 'l', "/dev/hd%c", 1, 15);
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/sd%c%d", -1, -1, 'a', 'p', "/dev/sd%c", 1, 15);
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/md%d", -1, -1, 0, 3, "/dev/md%d", 0, 0);
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/fd%d", -1, -1, 0, 1, "/dev/fd%d", 0, 0);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
Add_LVM_Disks();
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#elif defined(hpux)
|
|
Packit |
fcad23 |
#if defined(hpux10) || defined(hpux11)
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/rdsk/c%dt%xd%d", 0, 1, 0, 15,
|
|
Packit |
fcad23 |
"/dev/rdsk/c%dt%xd0", 0, 4);
|
|
Packit |
fcad23 |
#else /* hpux9 */
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/rdsk/c%dd%xs%d", 201, 201, 0, 15,
|
|
Packit |
fcad23 |
"/dev/rdsk/c%dd%xs0", 0, 4);
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#elif defined(solaris2)
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/rdsk/c%dt%dd0s%d", 0, 7, 0, 15,
|
|
Packit |
fcad23 |
"/dev/rdsk/c%dt%dd0s0", 0, 7);
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/rdsk/c%dd%ds%d", 0, 7, 0, 15,
|
|
Packit |
fcad23 |
"/dev/rdsk/c%dd%ds0", 0, 7);
|
|
Packit |
fcad23 |
#elif defined(darwin)
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/disk%ds%d", -1, -1, 0, 32, "/dev/disk%d", 1, 32);
|
|
Packit |
fcad23 |
#elif defined(freebsd4) || defined(freebsd5)
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/ad%ds%d%c", 0, 1, 1, 4, "/dev/ad%ds%d", 'a', 'h');
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/da%ds%d%c", 0, 1, 1, 4, "/dev/da%ds%d", 'a', 'h');
|
|
Packit |
fcad23 |
#elif defined(freebsd3)
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/wd%ds%d%c", 0, 1, 1, 4, "/dev/wd%ds%d", 'a',
|
|
Packit |
fcad23 |
'h');
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/sd%ds%d%c", 0, 1, 1, 4, "/dev/sd%ds%d", 'a',
|
|
Packit |
fcad23 |
'h');
|
|
Packit |
fcad23 |
#elif defined(freebsd2)
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/wd%d%c", -1, -1, 0, 3, "/dev/wd%d", 'a', 'h');
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/sd%d%c", -1, -1, 0, 3, "/dev/sd%d", 'a', 'h');
|
|
Packit |
fcad23 |
#elif defined(netbsd1)
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/wd%d%c", -1, -1, 0, 3, "/dev/wd%dc", 'a', 'h');
|
|
Packit |
fcad23 |
Add_HR_Disk_entry("/dev/sd%d%c", -1, -1, 0, 3, "/dev/sd%dc", 'a', 'h');
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
device_descr[HRDEV_DISK] = describe_disk;
|
|
Packit |
fcad23 |
HRD_savedModel[0] = '\0';
|
|
Packit |
fcad23 |
HRD_savedCapacity = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
for (i = 0; i < HRDEV_TYPE_MASK; ++i)
|
|
Packit |
fcad23 |
HRD_history[i] = -1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
REGISTER_MIB("host/hr_disk", hrdisk_variables, variable4,
|
|
Packit |
fcad23 |
hrdisk_variables_oid);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
snmpd_register_config_handler("ignoredisk", parse_disk_config,
|
|
Packit |
fcad23 |
free_disk_config, "name");
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
shutdown_hr_disk(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
#ifdef linux
|
|
Packit |
fcad23 |
Remove_LVM_Disks();
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#define ITEM_STRING 1
|
|
Packit |
fcad23 |
#define ITEM_SET 2
|
|
Packit |
fcad23 |
#define ITEM_STAR 3
|
|
Packit |
fcad23 |
#define ITEM_ANY 4
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
typedef unsigned char details_set[32];
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
typedef struct _conf_disk_item {
|
|
Packit |
fcad23 |
int item_type; /* ITEM_STRING, ITEM_SET, ITEM_STAR, ITEM_ANY */
|
|
Packit |
fcad23 |
void *item_details; /* content depends upon item_type */
|
|
Packit |
fcad23 |
struct _conf_disk_item *item_next;
|
|
Packit |
fcad23 |
} conf_disk_item;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
typedef struct _conf_disk_list {
|
|
Packit |
fcad23 |
conf_disk_item *list_item;
|
|
Packit |
fcad23 |
struct _conf_disk_list *list_next;
|
|
Packit |
fcad23 |
} conf_disk_list;
|
|
Packit |
fcad23 |
static conf_disk_list *conf_list = NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int match_disk_config(const char *);
|
|
Packit |
fcad23 |
static int match_disk_config_item(const char *, conf_disk_item *);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static void
|
|
Packit |
fcad23 |
parse_disk_config(const char *token, char *cptr)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
conf_disk_list *d_new = NULL;
|
|
Packit |
fcad23 |
conf_disk_item *di_curr = NULL;
|
|
Packit |
fcad23 |
details_set *d_set = NULL;
|
|
Packit |
fcad23 |
char *name = NULL, *p = NULL, *d_str = NULL, c;
|
|
Packit |
fcad23 |
unsigned int i, neg, c1, c2;
|
|
Packit |
fcad23 |
char *st = NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
name = strtok_r(cptr, " \t", &st);
|
|
Packit |
fcad23 |
if (!name) {
|
|
Packit |
fcad23 |
config_perror("Missing NAME parameter");
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
d_new = (conf_disk_list *) malloc(sizeof(conf_disk_list));
|
|
Packit |
fcad23 |
if (!d_new) {
|
|
Packit |
fcad23 |
config_perror("Out of memory");
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
di_curr = (conf_disk_item *) malloc(sizeof(conf_disk_item));
|
|
Packit |
fcad23 |
if (!di_curr) {
|
|
Packit |
fcad23 |
SNMP_FREE(d_new);
|
|
Packit |
fcad23 |
config_perror("Out of memory");
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
d_new->list_item = di_curr;
|
|
Packit |
fcad23 |
/* XXX: on error/return conditions we need to free the entire new
|
|
Packit |
fcad23 |
list, not just the last node like this is doing! */
|
|
Packit |
fcad23 |
for (;;) {
|
|
Packit |
fcad23 |
if (*name == '?') {
|
|
Packit |
fcad23 |
di_curr->item_type = ITEM_ANY;
|
|
Packit |
fcad23 |
di_curr->item_details = (void *) 0;
|
|
Packit |
fcad23 |
name++;
|
|
Packit |
fcad23 |
} else if (*name == '*') {
|
|
Packit |
fcad23 |
di_curr->item_type = ITEM_STAR;
|
|
Packit |
fcad23 |
di_curr->item_details = (void *) 0;
|
|
Packit |
fcad23 |
name++;
|
|
Packit |
fcad23 |
} else if (*name == '[') {
|
|
Packit |
fcad23 |
d_set = (details_set *) calloc(sizeof(details_set), 1);
|
|
Packit |
fcad23 |
if (!d_set) {
|
|
Packit |
fcad23 |
config_perror("Out of memory");
|
|
Packit |
fcad23 |
SNMP_FREE(d_new);
|
|
Packit |
fcad23 |
SNMP_FREE(di_curr);
|
|
Packit |
fcad23 |
SNMP_FREE(d_set);
|
|
Packit |
fcad23 |
SNMP_FREE(d_str);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
name++;
|
|
Packit |
fcad23 |
if (*name == '^' || *name == '!') {
|
|
Packit |
fcad23 |
neg = 1;
|
|
Packit |
fcad23 |
name++;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
neg = 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
while (*name && *name != ']') {
|
|
Packit |
fcad23 |
c1 = ((unsigned int) *name++) & 0xff;
|
|
Packit |
fcad23 |
if (*name == '-' && *(name + 1) != ']') {
|
|
Packit |
fcad23 |
name++;
|
|
Packit |
fcad23 |
c2 = ((unsigned int) *name++) & 0xff;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
c2 = c1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
for (i = c1; i <= c2; i++)
|
|
Packit |
fcad23 |
(*d_set)[i / 8] |= (unsigned char) (1 << (i % 8));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (*name != ']') {
|
|
Packit |
fcad23 |
config_perror
|
|
Packit |
fcad23 |
("Syntax error in NAME: invalid set specified");
|
|
Packit |
fcad23 |
SNMP_FREE(d_new);
|
|
Packit |
fcad23 |
SNMP_FREE(di_curr);
|
|
Packit |
fcad23 |
SNMP_FREE(d_set);
|
|
Packit |
fcad23 |
SNMP_FREE(d_str);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (neg) {
|
|
Packit |
fcad23 |
for (i = 0; i < sizeof(details_set); i++)
|
|
Packit |
fcad23 |
(*d_set)[i] = (*d_set)[i] ^ (unsigned char) 0xff;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
di_curr->item_type = ITEM_SET;
|
|
Packit |
fcad23 |
di_curr->item_details = (void *) d_set;
|
|
Packit |
fcad23 |
name++;
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
for (p = name;
|
|
Packit |
fcad23 |
*p != '\0' && *p != '?' && *p != '*' && *p != '['; p++);
|
|
Packit |
fcad23 |
c = *p;
|
|
Packit |
fcad23 |
*p = '\0';
|
|
Packit |
fcad23 |
d_str = strdup(name);
|
|
Packit |
fcad23 |
if (!d_str) {
|
|
Packit |
fcad23 |
SNMP_FREE(d_new);
|
|
Packit |
fcad23 |
SNMP_FREE(d_str);
|
|
Packit |
fcad23 |
SNMP_FREE(di_curr);
|
|
Packit |
fcad23 |
SNMP_FREE(d_set);
|
|
Packit |
fcad23 |
config_perror("Out of memory");
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
*p = c;
|
|
Packit |
fcad23 |
di_curr->item_type = ITEM_STRING;
|
|
Packit |
fcad23 |
di_curr->item_details = (void *) d_str;
|
|
Packit |
fcad23 |
name = p;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if (!*name) {
|
|
Packit |
fcad23 |
di_curr->item_next = (conf_disk_item *) 0;
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
di_curr->item_next =
|
|
Packit |
fcad23 |
(conf_disk_item *) malloc(sizeof(conf_disk_item));
|
|
Packit |
fcad23 |
if (!di_curr->item_next) {
|
|
Packit |
fcad23 |
SNMP_FREE(di_curr->item_next);
|
|
Packit |
fcad23 |
SNMP_FREE(d_new);
|
|
Packit |
fcad23 |
SNMP_FREE(di_curr);
|
|
Packit |
fcad23 |
SNMP_FREE(d_set);
|
|
Packit |
fcad23 |
SNMP_FREE(d_str);
|
|
Packit |
fcad23 |
config_perror("Out of memory");
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
di_curr = di_curr->item_next;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
d_new->list_next = conf_list;
|
|
Packit |
fcad23 |
conf_list = d_new;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static void
|
|
Packit |
fcad23 |
free_disk_config(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
conf_disk_list *d_ptr = conf_list, *d_next;
|
|
Packit |
fcad23 |
conf_disk_item *di_ptr, *di_next;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
while (d_ptr) {
|
|
Packit |
fcad23 |
d_next = d_ptr->list_next;
|
|
Packit |
fcad23 |
di_ptr = d_ptr->list_item;
|
|
Packit |
fcad23 |
while (di_ptr) {
|
|
Packit |
fcad23 |
di_next = di_ptr->item_next;
|
|
Packit |
fcad23 |
if (di_ptr->item_details)
|
|
Packit |
fcad23 |
free(di_ptr->item_details);
|
|
Packit |
fcad23 |
free((void *) di_ptr);
|
|
Packit |
fcad23 |
di_ptr = di_next;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
free((void *) d_ptr);
|
|
Packit |
fcad23 |
d_ptr = d_next;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
conf_list = (conf_disk_list *) 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int
|
|
Packit |
fcad23 |
match_disk_config_item(const char *name, conf_disk_item * di_ptr)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int result = 0;
|
|
Packit |
fcad23 |
size_t len;
|
|
Packit |
fcad23 |
details_set *d_set;
|
|
Packit |
fcad23 |
unsigned int c;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (di_ptr) {
|
|
Packit |
fcad23 |
switch (di_ptr->item_type) {
|
|
Packit |
fcad23 |
case ITEM_STRING:
|
|
Packit |
fcad23 |
len = strlen((const char *) di_ptr->item_details);
|
|
Packit |
fcad23 |
if (!strncmp(name, (const char *) di_ptr->item_details, len))
|
|
Packit |
fcad23 |
result = match_disk_config_item(name + len,
|
|
Packit |
fcad23 |
di_ptr->item_next);
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case ITEM_SET:
|
|
Packit |
fcad23 |
if (*name) {
|
|
Packit |
fcad23 |
d_set = (details_set *) di_ptr->item_details;
|
|
Packit |
fcad23 |
c = ((unsigned int) *name) & 0xff;
|
|
Packit |
fcad23 |
if ((*d_set)[c / 8] & (unsigned char) (1 << (c % 8)))
|
|
Packit |
fcad23 |
result = match_disk_config_item(name + 1,
|
|
Packit |
fcad23 |
di_ptr->item_next);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case ITEM_STAR:
|
|
Packit |
fcad23 |
if (di_ptr->item_next) {
|
|
Packit |
fcad23 |
for (; !result && *name; name++)
|
|
Packit |
fcad23 |
result = match_disk_config_item(name,
|
|
Packit |
fcad23 |
di_ptr->item_next);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
result = 1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case ITEM_ANY:
|
|
Packit |
fcad23 |
if (*name)
|
|
Packit |
fcad23 |
result = match_disk_config_item(name + 1,
|
|
Packit |
fcad23 |
di_ptr->item_next);
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
if (*name == '\0')
|
|
Packit |
fcad23 |
result = 1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return result;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int
|
|
Packit |
fcad23 |
match_disk_config(const char *name)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
conf_disk_list *d_ptr = conf_list;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
while (d_ptr) {
|
|
Packit |
fcad23 |
if (match_disk_config_item(name, d_ptr->list_item))
|
|
Packit |
fcad23 |
return 1; /* match found in ignorelist */
|
|
Packit |
fcad23 |
d_ptr = d_ptr->list_next;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* no match in ignorelist
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* header_hrdisk(...
|
|
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 |
int
|
|
Packit |
fcad23 |
header_hrdisk(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 |
#define HRDISK_ENTRY_NAME_LENGTH 11
|
|
Packit |
fcad23 |
oid newname[MAX_OID_LEN];
|
|
Packit |
fcad23 |
int disk_idx, LowIndex = -1;
|
|
Packit |
fcad23 |
int result;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk", "var_hrdisk: "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("host/hr_disk", name, *length));
|
|
Packit |
fcad23 |
DEBUGMSG(("host/hr_disk", " %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" disk entry
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
Init_HR_Disk();
|
|
Packit |
fcad23 |
for (;;) {
|
|
Packit |
fcad23 |
disk_idx = Get_Next_HR_Disk();
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk", "... index %d\n", disk_idx));
|
|
Packit |
fcad23 |
if (disk_idx == -1)
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
newname[HRDISK_ENTRY_NAME_LENGTH] = disk_idx;
|
|
Packit |
fcad23 |
result =
|
|
Packit |
fcad23 |
snmp_oid_compare(name, *length, newname,
|
|
Packit |
fcad23 |
(int) vp->namelen + 1);
|
|
Packit |
fcad23 |
if (exact && (result == 0)) {
|
|
Packit |
fcad23 |
LowIndex = disk_idx;
|
|
Packit |
fcad23 |
Save_HR_Disk_Specific();
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
if ((!exact && (result < 0)) &&
|
|
Packit |
fcad23 |
(LowIndex == -1 || disk_idx < LowIndex)) {
|
|
Packit |
fcad23 |
LowIndex = disk_idx;
|
|
Packit |
fcad23 |
Save_HR_Disk_Specific();
|
|
Packit |
fcad23 |
#ifdef HRD_MONOTONICALLY_INCREASING
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (LowIndex == -1) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk", "... index out of range\n"));
|
|
Packit |
fcad23 |
return (MATCH_FAILED);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
newname[HRDISK_ENTRY_NAME_LENGTH] = LowIndex;
|
|
Packit |
fcad23 |
memcpy((char *) name, (char *) newname,
|
|
Packit |
fcad23 |
((int) vp->namelen + 1) * sizeof(oid));
|
|
Packit |
fcad23 |
*length = vp->namelen + 1;
|
|
Packit |
fcad23 |
*write_method = (WriteMethod*)0;
|
|
Packit |
fcad23 |
*var_len = sizeof(long); /* default to 'long' results */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk", "... get disk stats "));
|
|
Packit |
fcad23 |
DEBUGMSGOID(("host/hr_disk", name, *length));
|
|
Packit |
fcad23 |
DEBUGMSG(("host/hr_disk", "\n"));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return LowIndex;
|
|
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_hrdisk(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 disk_idx;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
disk_idx =
|
|
Packit |
fcad23 |
header_hrdisk(vp, name, length, exact, var_len, write_method);
|
|
Packit |
fcad23 |
if (disk_idx == MATCH_FAILED)
|
|
Packit |
fcad23 |
return NULL;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
switch (vp->magic) {
|
|
Packit |
fcad23 |
case HRDISK_ACCESS:
|
|
Packit |
fcad23 |
long_return = Is_It_Writeable();
|
|
Packit |
fcad23 |
return (u_char *) & long_return;
|
|
Packit |
fcad23 |
case HRDISK_MEDIA:
|
|
Packit |
fcad23 |
long_return = What_Type_Disk();
|
|
Packit |
fcad23 |
return (u_char *) & long_return;
|
|
Packit |
fcad23 |
case HRDISK_REMOVEABLE:
|
|
Packit |
fcad23 |
long_return = Is_It_Removeable();
|
|
Packit |
fcad23 |
return (u_char *) & long_return;
|
|
Packit |
fcad23 |
case HRDISK_CAPACITY:
|
|
Packit |
fcad23 |
long_return = HRD_savedCapacity;
|
|
Packit |
fcad23 |
return (u_char *) & long_return;
|
|
Packit |
fcad23 |
default:
|
|
Packit |
fcad23 |
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrdisk\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 |
#define MAX_NUMBER_DISK_TYPES 16 /* probably should be a variable */
|
|
Packit |
fcad23 |
#define MAX_DISKS_PER_TYPE 15 /* SCSI disks - not a hard limit */
|
|
Packit |
fcad23 |
#define HRDISK_TYPE_SHIFT 4 /* log2 (MAX_DISKS_PER_TYPE+1) */
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
typedef struct {
|
|
Packit |
fcad23 |
const char *disk_devpart_string; /* printf() format disk part. name */
|
|
Packit |
fcad23 |
short disk_controller; /* controller id or -1 if NA */
|
|
Packit |
fcad23 |
short disk_device_first; /* first device id */
|
|
Packit |
fcad23 |
short disk_device_last; /* last device id */
|
|
Packit |
fcad23 |
const char *disk_devfull_string; /* printf() format full disk name */
|
|
Packit |
fcad23 |
short disk_partition_first; /* first partition id */
|
|
Packit |
fcad23 |
short disk_partition_last; /* last partition id */
|
|
Packit |
fcad23 |
} HRD_disk_t;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static HRD_disk_t disk_devices[MAX_NUMBER_DISK_TYPES];
|
|
Packit |
fcad23 |
static int HR_number_disk_types = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#if !(defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7))
|
|
Packit |
fcad23 |
static void
|
|
Packit |
fcad23 |
Add_HR_Disk_entry(const char *devpart_string,
|
|
Packit |
fcad23 |
int first_ctl,
|
|
Packit |
fcad23 |
int last_ctl,
|
|
Packit |
fcad23 |
int first_dev,
|
|
Packit |
fcad23 |
int last_dev,
|
|
Packit |
fcad23 |
const char *devfull_string,
|
|
Packit |
fcad23 |
int first_partn, int last_partn)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int lodev, hidev, nbr_created = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
while (first_ctl <= last_ctl) {
|
|
Packit |
fcad23 |
for (lodev = first_dev;
|
|
Packit |
fcad23 |
lodev <= last_dev && MAX_NUMBER_DISK_TYPES > HR_number_disk_types;
|
|
Packit |
fcad23 |
lodev += (1+MAX_DISKS_PER_TYPE), HR_number_disk_types++)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
nbr_created++;
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Split long runs of disks into separate "types"
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
hidev = lodev + MAX_DISKS_PER_TYPE;
|
|
Packit |
fcad23 |
if (last_dev < hidev)
|
|
Packit |
fcad23 |
hidev = last_dev;
|
|
Packit |
fcad23 |
disk_devices[HR_number_disk_types].disk_devpart_string =
|
|
Packit |
fcad23 |
devpart_string;
|
|
Packit |
fcad23 |
disk_devices[HR_number_disk_types].disk_controller = first_ctl;
|
|
Packit |
fcad23 |
disk_devices[HR_number_disk_types].disk_device_first = lodev;
|
|
Packit |
fcad23 |
disk_devices[HR_number_disk_types].disk_device_last = hidev;
|
|
Packit |
fcad23 |
disk_devices[HR_number_disk_types].disk_devfull_string =
|
|
Packit |
fcad23 |
devfull_string;
|
|
Packit |
fcad23 |
disk_devices[HR_number_disk_types].disk_partition_first =
|
|
Packit |
fcad23 |
first_partn;
|
|
Packit |
fcad23 |
disk_devices[HR_number_disk_types].disk_partition_last =
|
|
Packit |
fcad23 |
last_partn;
|
|
Packit |
fcad23 |
#if DEBUG_TEST
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk",
|
|
Packit |
fcad23 |
"Add_HR %02d '%s' first=%d last=%d\n",
|
|
Packit |
fcad23 |
HR_number_disk_types, devpart_string, lodev, hidev));
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
first_ctl++;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (nbr_created == 0 || MAX_NUMBER_DISK_TYPES < HR_number_disk_types) {
|
|
Packit |
fcad23 |
HR_number_disk_types = MAX_NUMBER_DISK_TYPES;
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk",
|
|
Packit |
fcad23 |
"WARNING! Add_HR_Disk_entry '%s' incomplete, %d created\n",
|
|
Packit |
fcad23 |
devpart_string, nbr_created));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#if DEBUG_TEST
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk",
|
|
Packit |
fcad23 |
"Add_HR_Disk_entry '%s' completed, %d created\n",
|
|
Packit |
fcad23 |
devpart_string, nbr_created));
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
void
|
|
Packit |
fcad23 |
Init_HR_Disk(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
HRD_type_index = 0;
|
|
Packit |
fcad23 |
HRD_index = -1;
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk", "Init_Disk\n"));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
Get_Next_HR_Disk(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
char string[PATH_MAX+1];
|
|
Packit |
fcad23 |
int fd, result;
|
|
Packit |
fcad23 |
int iindex;
|
|
Packit |
fcad23 |
int max_disks;
|
|
Packit |
fcad23 |
time_t now;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
HRD_index++;
|
|
Packit |
fcad23 |
time(&now;;
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk", "Next_Disk type %d of %d\n",
|
|
Packit |
fcad23 |
HRD_type_index, HR_number_disk_types));
|
|
Packit |
fcad23 |
while (HRD_type_index < HR_number_disk_types) {
|
|
Packit |
fcad23 |
max_disks = disk_devices[HRD_type_index].disk_device_last -
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_device_first + 1;
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk", "Next_Disk max %d of type %d\n",
|
|
Packit |
fcad23 |
max_disks, HRD_type_index));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
while (HRD_index < max_disks) {
|
|
Packit |
fcad23 |
iindex = (HRD_type_index << HRDISK_TYPE_SHIFT) + HRD_index;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Check to see whether this device
|
|
Packit |
fcad23 |
* has been probed for 'recently'
|
|
Packit |
fcad23 |
* and skip if so.
|
|
Packit |
fcad23 |
* This has a *major* impact on run
|
|
Packit |
fcad23 |
* times (by a factor of 10!)
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if ((HRD_history[iindex] > 0) &&
|
|
Packit |
fcad23 |
((now - HRD_history[iindex]) < 60)) {
|
|
Packit |
fcad23 |
HRD_index++;
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Construct the full device name in "string"
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (disk_devices[HRD_type_index].disk_controller != -1) {
|
|
Packit |
fcad23 |
snprintf(string, sizeof(string)-1,
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_devfull_string,
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_controller,
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_device_first +
|
|
Packit |
fcad23 |
HRD_index);
|
|
Packit |
fcad23 |
} else if (disk_devices[HRD_type_index].disk_device_first == disk_devices[HRD_type_index].disk_device_last) {
|
|
Packit |
fcad23 |
/* exact device name */
|
|
Packit |
fcad23 |
snprintf(string, sizeof(string)-1, "%s", disk_devices[HRD_type_index].disk_devfull_string);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
snprintf(string, sizeof(string)-1,
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_devfull_string,
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_device_first +
|
|
Packit |
fcad23 |
HRD_index);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
string[ sizeof(string)-1 ] = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk", "Get_Next_HR_Disk: %s (%d/%d)\n",
|
|
Packit |
fcad23 |
string, HRD_type_index, HRD_index));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (HRD_history[iindex] == -1) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* check whether this device is in the "ignoredisk" list in
|
|
Packit |
fcad23 |
* the config file. if yes this device will be marked as
|
|
Packit |
fcad23 |
* invalid for the future, i.e. it won't ever be checked
|
|
Packit |
fcad23 |
* again.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (match_disk_config(string)) {
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* device name matches entry in ignoredisk list
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk",
|
|
Packit |
fcad23 |
"Get_Next_HR_Disk: %s ignored\n", string));
|
|
Packit |
fcad23 |
HRD_history[iindex] = (time_t)LONG_MAX;
|
|
Packit |
fcad23 |
HRD_index++;
|
|
Packit |
fcad23 |
continue;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* use O_NDELAY to avoid CDROM spin-up and media detection
|
|
Packit |
fcad23 |
* * (too slow) --okir
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* at least with HP-UX 11.0 this doesn't seem to work properly
|
|
Packit |
fcad23 |
* * when accessing an empty CDROM device --jsf
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
#ifdef O_NDELAY /* I'm sure everything has it, but just in case... --Wes */
|
|
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 |
result = Query_Disk(fd, string);
|
|
Packit |
fcad23 |
close(fd);
|
|
Packit |
fcad23 |
if (result != -1) {
|
|
Packit |
fcad23 |
HRD_history[iindex] = 0;
|
|
Packit |
fcad23 |
return ((HRDEV_DISK << HRDEV_TYPE_SHIFT) + iindex);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk",
|
|
Packit |
fcad23 |
"Get_Next_HR_Disk: can't query %s\n", string));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk",
|
|
Packit |
fcad23 |
"Get_Next_HR_Disk: can't open %s\n", string));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
HRD_history[iindex] = now;
|
|
Packit |
fcad23 |
HRD_index++;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
HRD_type_index++;
|
|
Packit |
fcad23 |
HRD_index = 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
HRD_index = -1;
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
Get_Next_HR_Disk_Partition(char *string, size_t str_len, int HRP_index)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk", "Next_Partition type %d/%d:%d\n",
|
|
Packit |
fcad23 |
HRD_type_index, HRD_index, HRP_index));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* no more partition names => return -1
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (disk_devices[HRD_type_index].disk_partition_last -
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_partition_first + 1
|
|
Packit |
fcad23 |
<= HRP_index) {
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* Construct the partition name in "string"
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
if (disk_devices[HRD_type_index].disk_controller != -1) {
|
|
Packit |
fcad23 |
snprintf(string, str_len-1,
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_devpart_string,
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_controller,
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_device_first + HRD_index,
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_partition_first +
|
|
Packit |
fcad23 |
HRP_index);
|
|
Packit |
fcad23 |
} else {
|
|
Packit |
fcad23 |
snprintf(string, str_len-1,
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_devpart_string,
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_device_first + HRD_index,
|
|
Packit |
fcad23 |
disk_devices[HRD_type_index].disk_partition_first +
|
|
Packit |
fcad23 |
HRP_index);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
string[ str_len-1 ] = 0;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk",
|
|
Packit |
fcad23 |
"Get_Next_HR_Disk_Partition: %s (%d/%d:%d)\n", string,
|
|
Packit |
fcad23 |
HRD_type_index, HRD_index, HRP_index));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef darwin
|
|
Packit |
fcad23 |
int
|
|
Packit |
fcad23 |
Get_HR_Disk_Label(char *string, size_t str_len, const char *devfull)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
DASessionRef sess_ref;
|
|
Packit |
fcad23 |
DADiskRef disk;
|
|
Packit |
fcad23 |
CFDictionaryRef desc;
|
|
Packit |
fcad23 |
CFStringRef str_ref;
|
|
Packit |
fcad23 |
CFStringEncoding sys_encoding = CFStringGetSystemEncoding();
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk", "Disk Label type %s\n", devfull));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
sess_ref = DASessionCreate( NULL );
|
|
Packit |
fcad23 |
if (NULL == sess_ref) {
|
|
Packit |
fcad23 |
strlcpy(string, devfull, str_len);
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
disk = DADiskCreateFromBSDName( NULL, sess_ref, devfull );
|
|
Packit |
fcad23 |
if (NULL == disk) {
|
|
Packit |
fcad23 |
CFRelease(sess_ref);
|
|
Packit |
fcad23 |
strlcpy(string, devfull, str_len);
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
desc = DADiskCopyDescription( disk );
|
|
Packit |
fcad23 |
if (NULL == desc) {
|
|
Packit |
fcad23 |
snmp_log(LOG_ERR,
|
|
Packit |
fcad23 |
"diskmgr: couldn't get disk description for %s, skipping\n",
|
|
Packit |
fcad23 |
devfull);
|
|
Packit |
fcad23 |
CFRelease(disk);
|
|
Packit |
fcad23 |
CFRelease(sess_ref);
|
|
Packit |
fcad23 |
strlcpy(string, devfull, str_len);
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** model */
|
|
Packit |
fcad23 |
str_ref = (CFStringRef)
|
|
Packit |
fcad23 |
CFDictionaryGetValue(desc, kDADiskDescriptionMediaNameKey);
|
|
Packit |
fcad23 |
if (str_ref) {
|
|
Packit |
fcad23 |
strlcpy(string, CFStringGetCStringPtr(str_ref, sys_encoding),
|
|
Packit |
fcad23 |
str_len);
|
|
Packit |
fcad23 |
DEBUGMSGTL(("verbose:diskmgr:darwin", " name %s\n", string));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
strlcpy(string, devfull, str_len);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
CFRelease(disk);
|
|
Packit |
fcad23 |
CFRelease(desc);
|
|
Packit |
fcad23 |
CFRelease(sess_ref);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static void
|
|
Packit |
fcad23 |
Save_HR_Disk_Specific(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
#ifdef DIOC_DESCRIBE
|
|
Packit |
fcad23 |
HRD_savedIntf_type = HRD_info.intf_type;
|
|
Packit |
fcad23 |
HRD_savedDev_type = HRD_info.dev_type;
|
|
Packit |
fcad23 |
HRD_savedFlags = HRD_info.flags;
|
|
Packit |
fcad23 |
HRD_savedCapacity = HRD_cap.lba / 2;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#ifdef DKIOCINFO
|
|
Packit |
fcad23 |
HRD_savedCtrl_type = HRD_info.dki_ctype;
|
|
Packit |
fcad23 |
HRD_savedFlags = HRD_info.dki_flags;
|
|
Packit |
fcad23 |
HRD_savedCapacity = HRD_cap.dkg_ncyl * HRD_cap.dkg_nhead * HRD_cap.dkg_nsect / 2; /* ??? */
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#ifdef HAVE_LINUX_HDREG_H
|
|
Packit |
fcad23 |
HRD_savedCapacity = HRD_info.lba_capacity / 2;
|
|
Packit |
fcad23 |
HRD_savedFlags = HRD_info.config;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#ifdef DIOCGDINFO
|
|
Packit |
fcad23 |
HRD_savedCapacity = HRD_info.d_secperunit / 2;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#ifdef darwin
|
|
Packit |
fcad23 |
HRD_savedCapacity = HRD_cap / 1024;
|
|
Packit |
fcad23 |
HRD_saved_access = HRD_access;
|
|
Packit |
fcad23 |
HRD_saved_type = HRD_type;
|
|
Packit |
fcad23 |
HRD_saved_removeble = HRD_removeble;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static void
|
|
Packit |
fcad23 |
Save_HR_Disk_General(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
#ifdef DIOC_DESCRIBE
|
|
Packit |
fcad23 |
strlcpy(HRD_savedModel, HRD_info.model_num, sizeof(HRD_savedModel));
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#ifdef DKIOCINFO
|
|
Packit |
fcad23 |
strlcpy(HRD_savedModel, HRD_info.dki_dname, sizeof(HRD_savedModel));
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#ifdef HAVE_LINUX_HDREG_H
|
|
Packit |
fcad23 |
strlcpy(HRD_savedModel, (const char *) HRD_info.model,
|
|
Packit |
fcad23 |
sizeof(HRD_savedModel));
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#ifdef DIOCGDINFO
|
|
Packit |
fcad23 |
strlcpy(HRD_savedModel, dktypenames[HRD_info.d_type],
|
|
Packit |
fcad23 |
sizeof(HRD_savedModel));
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#ifdef darwin
|
|
Packit |
fcad23 |
strlcpy(HRD_savedModel, HRD_model, sizeof(HRD_savedModel));
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static const char *
|
|
Packit |
fcad23 |
describe_disk(int idx)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
if (HRD_savedModel[0] == '\0')
|
|
Packit |
fcad23 |
return ("some sort of disk");
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
return (HRD_savedModel);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int
|
|
Packit |
fcad23 |
Query_Disk(int fd, const char *devfull)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int result = -1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef DIOC_DESCRIBE
|
|
Packit |
fcad23 |
result = ioctl(fd, DIOC_DESCRIBE, &HRD_info);
|
|
Packit |
fcad23 |
if (result != -1)
|
|
Packit |
fcad23 |
result = ioctl(fd, DIOC_CAPACITY, &HRD_cap);
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef DKIOCINFO
|
|
Packit |
fcad23 |
result = ioctl(fd, DKIOCINFO, &HRD_info);
|
|
Packit |
fcad23 |
if (result != -1)
|
|
Packit |
fcad23 |
result = ioctl(fd, DKIOCGGEOM, &HRD_cap);
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef HAVE_LINUX_HDREG_H
|
|
Packit |
fcad23 |
if (HRD_type_index == 0) /* IDE hard disk */
|
|
Packit |
fcad23 |
result = ioctl(fd, HDIO_GET_IDENTITY, &HRD_info);
|
|
Packit |
fcad23 |
else if (HRD_type_index != 3) { /* SCSI hard disk, md and LVM devices */
|
|
Packit |
fcad23 |
long h;
|
|
Packit |
fcad23 |
result = ioctl(fd, BLKGETSIZE, &h);
|
|
Packit |
fcad23 |
if (result != -1 && HRD_type_index == 2 && h == 0L)
|
|
Packit |
fcad23 |
result = -1; /* ignore empty md devices */
|
|
Packit |
fcad23 |
if (result != -1) {
|
|
Packit |
fcad23 |
HRD_info.lba_capacity = h;
|
|
Packit |
fcad23 |
if (HRD_type_index == 1)
|
|
Packit |
fcad23 |
snprintf( (char *) HRD_info.model, sizeof(HRD_info.model)-1,
|
|
Packit |
fcad23 |
"SCSI disk (%s)", devfull);
|
|
Packit |
fcad23 |
else if (HRD_type_index >= 4)
|
|
Packit |
fcad23 |
snprintf( (char *) HRD_info.model, sizeof(HRD_info.model)-1,
|
|
Packit |
fcad23 |
"LVM volume (%s)", devfull + strlen("/dev/mapper/"));
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
snprintf( (char *) HRD_info.model, sizeof(HRD_info.model)-1,
|
|
Packit |
fcad23 |
"RAID disk (%s)", devfull);
|
|
Packit |
fcad23 |
HRD_info.model[ sizeof(HRD_info.model)-1 ] = 0;
|
|
Packit |
fcad23 |
HRD_info.config = 0;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef DIOCGDINFO
|
|
Packit |
fcad23 |
result = ioctl(fd, DIOCGDINFO, &HRD_info);
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef darwin
|
|
Packit |
fcad23 |
DASessionRef sess_ref;
|
|
Packit |
fcad23 |
DADiskRef disk;
|
|
Packit |
fcad23 |
CFDictionaryRef desc;
|
|
Packit |
fcad23 |
CFStringRef str_ref;
|
|
Packit |
fcad23 |
CFNumberRef number_ref;
|
|
Packit |
fcad23 |
CFBooleanRef bool_ref;
|
|
Packit |
fcad23 |
CFStringEncoding sys_encoding = CFStringGetSystemEncoding();
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
sess_ref = DASessionCreate( NULL );
|
|
Packit |
fcad23 |
if (NULL == sess_ref)
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
disk = DADiskCreateFromBSDName( NULL, sess_ref, devfull );
|
|
Packit |
fcad23 |
if (NULL == disk) {
|
|
Packit |
fcad23 |
CFRelease(sess_ref);
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
desc = DADiskCopyDescription( disk );
|
|
Packit |
fcad23 |
if (NULL == desc) {
|
|
Packit |
fcad23 |
CFRelease(disk);
|
|
Packit |
fcad23 |
CFRelease(sess_ref);
|
|
Packit |
fcad23 |
return -1;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
number_ref = (CFNumberRef)
|
|
Packit |
fcad23 |
CFDictionaryGetValue(desc, kDADiskDescriptionMediaSizeKey);
|
|
Packit |
fcad23 |
if (number_ref)
|
|
Packit |
fcad23 |
CFNumberGetValue(number_ref, kCFNumberSInt64Type, &HRD_cap);
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
HRD_cap = 0;
|
|
Packit |
fcad23 |
DEBUGMSGTL(("verbose:diskmgr:darwin", " size %lld\n", HRD_cap));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** writable? */
|
|
Packit |
fcad23 |
bool_ref = (CFBooleanRef)
|
|
Packit |
fcad23 |
CFDictionaryGetValue(desc, kDADiskDescriptionMediaWritableKey);
|
|
Packit |
fcad23 |
if (bool_ref) {
|
|
Packit |
fcad23 |
HRD_access = CFBooleanGetValue(bool_ref);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
HRD_access = 0;
|
|
Packit |
fcad23 |
DEBUGMSGTL(("verbose:diskmgr:darwin", " writable %d\n",
|
|
Packit |
fcad23 |
HRD_access));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** removable? */
|
|
Packit |
fcad23 |
bool_ref = (CFBooleanRef)
|
|
Packit |
fcad23 |
CFDictionaryGetValue(desc, kDADiskDescriptionMediaRemovableKey);
|
|
Packit |
fcad23 |
if (bool_ref) {
|
|
Packit |
fcad23 |
HRD_removeble = CFBooleanGetValue(bool_ref);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
HRD_removeble = 0;
|
|
Packit |
fcad23 |
DEBUGMSGTL(("verbose:diskmgr:darwin", " removable %d\n",
|
|
Packit |
fcad23 |
HRD_removeble));
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** get type */
|
|
Packit |
fcad23 |
str_ref = (CFStringRef)
|
|
Packit |
fcad23 |
CFDictionaryGetValue(desc, kDADiskDescriptionMediaTypeKey);
|
|
Packit |
fcad23 |
if (str_ref) {
|
|
Packit |
fcad23 |
HRD_type = _get_type_value(CFStringGetCStringPtr(str_ref,
|
|
Packit |
fcad23 |
sys_encoding));
|
|
Packit |
fcad23 |
DEBUGMSGTL(("verbose:diskmgr:darwin", " type %s / %d\n",
|
|
Packit |
fcad23 |
CFStringGetCStringPtr(str_ref, sys_encoding),
|
|
Packit |
fcad23 |
HRD_type));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else {
|
|
Packit |
fcad23 |
str_ref = (CFStringRef)
|
|
Packit |
fcad23 |
CFDictionaryGetValue(desc, kDADiskDescriptionDeviceProtocolKey);
|
|
Packit |
fcad23 |
if (str_ref) {
|
|
Packit |
fcad23 |
HRD_type =
|
|
Packit |
fcad23 |
_get_type_from_protocol(CFStringGetCStringPtr(str_ref,
|
|
Packit |
fcad23 |
sys_encoding));
|
|
Packit |
fcad23 |
DEBUGMSGTL(("verbose:diskmgr:darwin", " type %s / %d\n",
|
|
Packit |
fcad23 |
CFStringGetCStringPtr(str_ref, sys_encoding),
|
|
Packit |
fcad23 |
HRD_type));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
HRD_type = HRDISKSTORAGEMEDIA_UNKNOWN;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/** model */
|
|
Packit |
fcad23 |
str_ref = (CFStringRef)
|
|
Packit |
fcad23 |
CFDictionaryGetValue(desc, kDADiskDescriptionDeviceModelKey);
|
|
Packit |
fcad23 |
if (str_ref) {
|
|
Packit |
fcad23 |
strlcpy(HRD_model, CFStringGetCStringPtr(str_ref, sys_encoding),
|
|
Packit |
fcad23 |
sizeof(HRD_model));
|
|
Packit |
fcad23 |
DEBUGMSGTL(("verbose:diskmgr:darwin", " model %s\n", HRD_model));
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
HRD_model[0] = 0;
|
|
Packit |
fcad23 |
CFRelease(disk);
|
|
Packit |
fcad23 |
CFRelease(desc);
|
|
Packit |
fcad23 |
CFRelease(sess_ref);
|
|
Packit |
fcad23 |
result = 0;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return (result);
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int
|
|
Packit |
fcad23 |
Is_It_Writeable(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
#ifdef DIOC_DESCRIBE
|
|
Packit |
fcad23 |
if ((HRD_savedFlags & WRITE_PROTECT_FLAG) ||
|
|
Packit |
fcad23 |
(HRD_savedDev_type == CDROM_DEV_TYPE))
|
|
Packit |
fcad23 |
return (2); /* read only */
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef DKIOCINFO
|
|
Packit |
fcad23 |
if (HRD_savedCtrl_type == DKC_CDROM)
|
|
Packit |
fcad23 |
return (2); /* read only */
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef darwin
|
|
Packit |
fcad23 |
if (!HRD_access)
|
|
Packit |
fcad23 |
return (2);
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return (1); /* read-write */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int
|
|
Packit |
fcad23 |
What_Type_Disk(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
#ifdef DIOC_DESCRIBE
|
|
Packit |
fcad23 |
switch (HRD_savedDev_type) {
|
|
Packit |
fcad23 |
case DISK_DEV_TYPE:
|
|
Packit |
fcad23 |
if (HRD_savedIntf_type == PC_FDC_INTF)
|
|
Packit |
fcad23 |
return (4); /* Floppy Disk */
|
|
Packit |
fcad23 |
else
|
|
Packit |
fcad23 |
return (3); /* Hard Disk */
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case CDROM_DEV_TYPE:
|
|
Packit |
fcad23 |
return (5); /* Optical RO */
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case WORM_DEV_TYPE:
|
|
Packit |
fcad23 |
return (6); /* Optical WORM */
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case MO_DEV_TYPE:
|
|
Packit |
fcad23 |
return (7); /* Optical R/W */
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
default:
|
|
Packit |
fcad23 |
return (2); /* Unknown */
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef DKIOCINFO
|
|
Packit |
fcad23 |
switch (HRD_savedCtrl_type) {
|
|
Packit |
fcad23 |
case DKC_WDC2880:
|
|
Packit |
fcad23 |
case DKC_DSD5215:
|
|
Packit |
fcad23 |
#ifdef DKC_XY450
|
|
Packit |
fcad23 |
case DKC_XY450:
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
case DKC_ACB4000:
|
|
Packit |
fcad23 |
case DKC_MD21:
|
|
Packit |
fcad23 |
#ifdef DKC_XD7053
|
|
Packit |
fcad23 |
case DKC_XD7053:
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
case DKC_SCSI_CCS:
|
|
Packit |
fcad23 |
#ifdef DKC_PANTHER
|
|
Packit |
fcad23 |
case DKC_PANTHER:
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#ifdef DKC_CDC_9057
|
|
Packit |
fcad23 |
case DKC_CDC_9057:
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
#ifdef DKC_FJ_M1060
|
|
Packit |
fcad23 |
case DKC_FJ_M1060:
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
case DKC_DIRECT:
|
|
Packit |
fcad23 |
case DKC_PCMCIA_ATA:
|
|
Packit |
fcad23 |
return (3); /* Hard Disk */
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case DKC_NCRFLOPPY:
|
|
Packit |
fcad23 |
case DKC_SMSFLOPPY:
|
|
Packit |
fcad23 |
case DKC_INTEL82077:
|
|
Packit |
fcad23 |
return (4); /* Floppy Disk */
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case DKC_CDROM:
|
|
Packit |
fcad23 |
return (5); /* Optical RO */
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case DKC_PCMCIA_MEM:
|
|
Packit |
fcad23 |
return (8); /* RAM disk */
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
case DKC_MD: /* "meta-disk" driver */
|
|
Packit |
fcad23 |
return (1); /* Other */
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef darwin
|
|
Packit |
fcad23 |
return HRD_type;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return (2); /* Unknown */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int
|
|
Packit |
fcad23 |
Is_It_Removeable(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
#ifdef DIOC_DESCRIBE
|
|
Packit |
fcad23 |
if ((HRD_savedIntf_type == PC_FDC_INTF) ||
|
|
Packit |
fcad23 |
(HRD_savedDev_type == WORM_DEV_TYPE) ||
|
|
Packit |
fcad23 |
(HRD_savedDev_type == MO_DEV_TYPE) ||
|
|
Packit |
fcad23 |
(HRD_savedDev_type == CDROM_DEV_TYPE))
|
|
Packit |
fcad23 |
return (1); /* true */
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef DKIOCINFO
|
|
Packit |
fcad23 |
if ((HRD_savedCtrl_type == DKC_CDROM) ||
|
|
Packit |
fcad23 |
(HRD_savedCtrl_type == DKC_NCRFLOPPY) ||
|
|
Packit |
fcad23 |
(HRD_savedCtrl_type == DKC_SMSFLOPPY) ||
|
|
Packit |
fcad23 |
(HRD_savedCtrl_type == DKC_INTEL82077) ||
|
|
Packit |
fcad23 |
(HRD_savedCtrl_type == DKC_PCMCIA_MEM) ||
|
|
Packit |
fcad23 |
(HRD_savedCtrl_type == DKC_PCMCIA_ATA))
|
|
Packit |
fcad23 |
return (1); /* true */
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef HAVE_LINUX_HDREG_H
|
|
Packit |
fcad23 |
if (HRD_savedFlags & 0x80)
|
|
Packit |
fcad23 |
return (1); /* true */
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef darwin
|
|
Packit |
fcad23 |
if (HRD_removeble)
|
|
Packit |
fcad23 |
return (1);
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return (2); /* false */
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef darwin
|
|
Packit |
fcad23 |
typedef struct type_value_map_s {
|
|
Packit |
fcad23 |
const char *type;
|
|
Packit |
fcad23 |
uint32_t value;
|
|
Packit |
fcad23 |
} type_value_map;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static type_value_map media_type_map[] = {
|
|
Packit |
fcad23 |
{ "CD-ROM", HRDISKSTORAGEMEDIA_OPTICALDISKROM},
|
|
Packit |
fcad23 |
{ "DVD-R", HRDISKSTORAGEMEDIA_OPTICALDISKWORM},
|
|
Packit |
fcad23 |
{ "DVD+R", HRDISKSTORAGEMEDIA_OPTICALDISKWORM},
|
|
Packit |
fcad23 |
};
|
|
Packit |
fcad23 |
static int media_types = sizeof(media_type_map)/sizeof(media_type_map[0]);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int
|
|
Packit |
fcad23 |
_get_type_value( const char *str_type )
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int i, len;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (NULL == str_type)
|
|
Packit |
fcad23 |
return HRDISKSTORAGEMEDIA_UNKNOWN;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
len = strlen(str_type);
|
|
Packit |
fcad23 |
for(i=0; i < media_types; ++i) {
|
|
Packit |
fcad23 |
if (0 == strcmp(media_type_map[i].type, str_type))
|
|
Packit |
fcad23 |
return media_type_map[i].value;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return HRDISKSTORAGEMEDIA_UNKNOWN;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static type_value_map proto_map[] = {
|
|
Packit |
fcad23 |
{ "ATA", HRDISKSTORAGEMEDIA_HARDDISK},
|
|
Packit |
fcad23 |
{ "ATAPI", HRDISKSTORAGEMEDIA_OPTICALDISKROM}
|
|
Packit |
fcad23 |
};
|
|
Packit |
fcad23 |
static int proto_maps = sizeof(proto_map)/sizeof(proto_map[0]);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static int _get_type_from_protocol( const char *prot )
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
int i, len;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
if (NULL == prot)
|
|
Packit |
fcad23 |
return TV_FALSE;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
len = strlen(prot);
|
|
Packit |
fcad23 |
for(i=0; i < proto_maps; ++i) {
|
|
Packit |
fcad23 |
if (0 == strcmp(proto_map[i].type, prot))
|
|
Packit |
fcad23 |
return proto_map[i].value;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
return HRDISKSTORAGEMEDIA_UNKNOWN;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
#ifdef linux
|
|
Packit |
fcad23 |
#if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP)
|
|
Packit |
fcad23 |
static char *lvm_device_names[MAX_NUMBER_DISK_TYPES];
|
|
Packit |
fcad23 |
static int lvm_device_count;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static void
|
|
Packit |
fcad23 |
Add_LVM_Disks(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
#if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP)
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* LVM devices are harder because their name can be almost anything (see
|
|
Packit |
fcad23 |
* regexp below). Each logical volume is interpreted as its own device with
|
|
Packit |
fcad23 |
* one partition, even if two logical volumes share common volume group.
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
regex_t lvol;
|
|
Packit |
fcad23 |
int res;
|
|
Packit |
fcad23 |
DIR *dir;
|
|
Packit |
fcad23 |
struct dirent *d;
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
res =
|
|
Packit |
fcad23 |
regcomp(&lvol, "[0-9a-zA-Z+_\\.-]+-[0-9a-zA-Z+_\\.-]+",
|
|
Packit |
fcad23 |
REG_EXTENDED | REG_NOSUB);
|
|
Packit |
fcad23 |
if (res != 0) {
|
|
Packit |
fcad23 |
char error[200];
|
|
Packit |
fcad23 |
regerror(res, &lvol, error, sizeof(error)-1);
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk",
|
|
Packit |
fcad23 |
"Add_LVM_Disks: cannot compile regexp: %s", error));
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
dir = opendir("/dev/mapper/");
|
|
Packit |
fcad23 |
if (dir == NULL) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk",
|
|
Packit |
fcad23 |
"Add_LVM_Disks: cannot open /dev/mapper"));
|
|
Packit |
fcad23 |
regfree(&lvol);
|
|
Packit |
fcad23 |
return;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
while ((d = readdir(dir)) != NULL) {
|
|
Packit |
fcad23 |
res = regexec(&lvol, d->d_name, 0, NULL, 0);
|
|
Packit |
fcad23 |
if (res == 0) {
|
|
Packit |
fcad23 |
char *path = (char*)malloc(PATH_MAX + 1);
|
|
Packit |
fcad23 |
if (path == NULL) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk",
|
|
Packit |
fcad23 |
"Add_LVM_Disks: cannot allocate memory for device %s",
|
|
Packit |
fcad23 |
d->d_name));
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
snprintf(path, PATH_MAX-1, "/dev/mapper/%s", d->d_name);
|
|
Packit |
fcad23 |
Add_HR_Disk_entry(path, -1, -1, 0, 0, path, 0, 0);
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* store the device name so we can free it in Remove_LVM_Disks
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
lvm_device_names[lvm_device_count] = path;
|
|
Packit |
fcad23 |
++lvm_device_count;
|
|
Packit |
fcad23 |
if (lvm_device_count >= MAX_NUMBER_DISK_TYPES) {
|
|
Packit |
fcad23 |
DEBUGMSGTL(("host/hr_disk",
|
|
Packit |
fcad23 |
"Add_LVM_Disks: maximum count of LVM devices reached"));
|
|
Packit |
fcad23 |
break;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
closedir(dir);
|
|
Packit |
fcad23 |
regfree(&lvol);
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
|
|
Packit |
fcad23 |
static void
|
|
Packit |
fcad23 |
Remove_LVM_Disks(void)
|
|
Packit |
fcad23 |
{
|
|
Packit |
fcad23 |
#if defined(HAVE_REGEX_H) && defined(HAVE_REGCOMP)
|
|
Packit |
fcad23 |
/*
|
|
Packit |
fcad23 |
* just free the device names allocated in add_lvm_disks
|
|
Packit |
fcad23 |
*/
|
|
Packit |
fcad23 |
int i;
|
|
Packit |
fcad23 |
for (i = 0; i < lvm_device_count; i++) {
|
|
Packit |
fcad23 |
free(lvm_device_names[i]);
|
|
Packit |
fcad23 |
lvm_device_names[i] = NULL;
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
lvm_device_count = 0;
|
|
Packit |
fcad23 |
#endif
|
|
Packit |
fcad23 |
}
|
|
Packit |
fcad23 |
#endif
|