blob: 60a1629fbeefaae8a92b5e212d9531e3e1e87b21 [file] [log] [blame]
/*
* Host Resources MIB - File System device group implementation - hr_filesys.c
*
*/
/* Portions of this file are subject to the following copyright(s). See
* the Net-SNMP's COPYING file for more details and other copyrights
* that may apply:
*/
/*
* Portions of this file are copyrighted by:
* Copyright (C) 2007 Apple, Inc. All rights reserved.
* Use is subject to license terms specified in the COPYING file
* distributed with the Net-SNMP package.
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/agent/hardware/memory.h>
#include "host_res.h"
#include "hr_filesys.h"
#include "hr_storage.h"
#include "hr_disk.h"
#include <net-snmp/utilities.h>
#if HAVE_MNTENT_H
#include <mntent.h>
#endif
#if HAVE_SYS_MNTENT_H
#include <sys/mntent.h>
#endif
#if HAVE_SYS_MNTTAB_H
#include <sys/mnttab.h>
#endif
#if HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
#if HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
#include <ctype.h>
#if HAVE_STRING_H
#include <string.h>
#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_NBUTIL_H
#include <nbutil.h>
#endif
#if defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
#include <sys/mntctl.h>
#include <sys/vmount.h>
#include <sys/statfs.h>
#endif
#if defined(bsdi4) || defined(freebsd3) || defined(freebsd4) || defined(freebsd5) || defined(darwin)
#if HAVE_GETFSSTAT && defined(MFSNAMELEN)
#define MOUNT_NFS "nfs"
#define MNTTYPE_UFS "ufs"
#define BerkelyFS
#define MNTTYPE_FFS "ffs"
#define MNTTYPE_NFS "nfs"
#define MNTTYPE_NFS3 "nfs"
#define MNTTYPE_HFS "hfs"
#define MNTTYPE_MFS "mfs"
#define MNTTYPE_MSDOS "msdos"
#define MNTTYPE_LFS "lfs"
#define MNTTYPE_FDESC "fdesc"
#define MNTTYPE_PORTAL "portal"
#define MNTTYPE_NULL "null"
#define MNTTYPE_UMAP "umap"
#define MNTTYPE_KERNFS "kernfs"
#define MNTTYPE_PROCFS "procfs"
#define MNTTYPE_AFS "afs"
#define MNTTYPE_CD9660 "cd9660"
#define MNTTYPE_UNION "union"
#define MNTTYPE_ADOSFS "adosfs"
#define MNTTYPE_EXT2FS "ext2fs"
#define MNTTYPE_CFS "coda"
#define MNTTYPE_NTFS "ntfs"
#endif
#endif /* freebsd3 */
#define HRFS_MONOTONICALLY_INCREASING
/*********************
*
* Kernel & interface information,
* and internal forward declarations
*
*********************/
#ifdef solaris2
struct mnttab HRFS_entry_struct;
struct mnttab *HRFS_entry = &HRFS_entry_struct;
#define HRFS_name mnt_special
#define HRFS_mount mnt_mountp
#define HRFS_type mnt_fstype
#define HRFS_statfs statvfs
#elif defined(HAVE_STATVFS) && defined(__NetBSD__)
#if !defined(MFSNAMELEN) && defined(_VFS_NAMELEN)
#define MFSNAMELEN _VFS_NAMELEN
#endif
#define getfsstat getvfsstat
static struct statvfs *fsstats = NULL;
struct statvfs *HRFS_entry;
static int fscount;
#define HRFS_mount f_mntonname
#define HRFS_name f_mntfromname
#define HRFS_statfs statvfs
#define HRFS_type f_fstypename
#elif defined(HAVE_GETFSSTAT) && !defined(HAVE_STATFS) && defined(HAVE_STATVFS)
static struct statfs *fsstats = NULL;
struct statfs *HRFS_entry;
static int fscount;
#define HRFS_mount f_mntonname
#define HRFS_name f_mntfromname
#define HRFS_statfs statvfs
#define HRFS_type f_fstypename
#elif defined(HAVE_GETFSSTAT)
static struct statfs *fsstats = 0;
static int fscount;
struct statfs *HRFS_entry;
#define HRFS_statfs statfs
#ifdef MFSNAMELEN
#define HRFS_type f_fstypename
#else
#define HRFS_type f_type
#endif
#define HRFS_mount f_mntonname
#define HRFS_name f_mntfromname
#elif defined(dynix)
struct mntent *HRFS_entry;
#define HRFS_name mnt_fsname
#define HRFS_mount mnt_dir
#define HRFS_type mnt_type
#define HRFS_statfs statvfs
#elif defined(WIN32)
struct win_statfs *HRFS_entry;
static int fscount;
#define HRFS_mount f_driveletter
#define HRFS_name f_fsid
#define HRFS_statfs win_statfs
#define HRFS_type f_type
#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
struct vmount *aixmnt, *aixcurr;
struct HRFS_entry {
char *HRFS_name;
char *HRFS_mount;
int HRFS_type;
int HRFS_flags;
} *HRFS_entry;
#define HRFS_statfs statfs
#else
struct mntent *HRFS_entry;
#define HRFS_name mnt_fsname
#define HRFS_mount mnt_dir
#define HRFS_type mnt_type
#define HRFS_statfs statfs
#ifdef linux
#define MNTTYPE_CD9660 "iso9660"
#define MNTTYPE_EXT2FS "ext2"
#define MNTTYPE_EXT3FS "ext3"
#define MNTTYPE_SMBFS "smbfs"
#define MNTTYPE_MSDOS "msdos"
#define MNTTYPE_FAT32 "vfat"
#define MNTTYPE_NTFS "ntfs"
#define MNTTYPE_NFS4 "nfs4"
#endif /* linux */
#endif
#define FULL_DUMP 0
#define PART_DUMP 1
extern void Init_HR_FileSys(void);
extern int Get_Next_HR_FileSys(void);
char *cook_device(char *);
static u_char *when_dumped(char *filesys, int level, size_t * length);
int header_hrfilesys(struct variable *, oid *, size_t *, int,
size_t *, WriteMethod **);
/*********************
*
* Initialisation & common implementation functions
*
*********************/
#define HRFSYS_INDEX 1
#define HRFSYS_MOUNT 2
#define HRFSYS_RMOUNT 3
#define HRFSYS_TYPE 4
#define HRFSYS_ACCESS 5
#define HRFSYS_BOOT 6
#define HRFSYS_STOREIDX 7
#define HRFSYS_FULLDUMP 8
#define HRFSYS_PARTDUMP 9
struct variable4 hrfsys_variables[] = {
{HRFSYS_INDEX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_hrfilesys, 2, {1, 1}},
{HRFSYS_MOUNT, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_hrfilesys, 2, {1, 2}},
{HRFSYS_RMOUNT, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_hrfilesys, 2, {1, 3}},
{HRFSYS_TYPE, ASN_OBJECT_ID, NETSNMP_OLDAPI_RONLY,
var_hrfilesys, 2, {1, 4}},
{HRFSYS_ACCESS, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_hrfilesys, 2, {1, 5}},
{HRFSYS_BOOT, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_hrfilesys, 2, {1, 6}},
{HRFSYS_STOREIDX, ASN_INTEGER, NETSNMP_OLDAPI_RONLY,
var_hrfilesys, 2, {1, 7}},
{HRFSYS_FULLDUMP, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_hrfilesys, 2, {1, 8}},
{HRFSYS_PARTDUMP, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
var_hrfilesys, 2, {1, 9}},
};
oid hrfsys_variables_oid[] = { 1, 3, 6, 1, 2, 1, 25, 3, 8 };
void
init_hr_filesys(void)
{
REGISTER_MIB("host/hr_filesys", hrfsys_variables, variable4,
hrfsys_variables_oid);
#if defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
/* something leaks, make it idiot-safe */
aixmnt = NULL;
aixcurr = NULL;
#endif
}
/*
* header_hrfilesys(...
* Arguments:
* vp IN - pointer to variable entry that points here
* name IN/OUT - IN/name requested, OUT/name found
* length IN/OUT - length of IN/OUT oid's
* exact IN - TRUE if an exact match was requested
* var_len OUT - length of variable or 0 if function returned
* write_method
*
*/
int
header_hrfilesys(struct variable *vp,
oid * name,
size_t * length,
int exact, size_t * var_len, WriteMethod ** write_method)
{
#define HRFSYS_ENTRY_NAME_LENGTH 11
oid newname[MAX_OID_LEN];
int fsys_idx, LowIndex = -1;
int result;
DEBUGMSGTL(("host/hr_filesys", "var_hrfilesys: "));
DEBUGMSGOID(("host/hr_filesys", name, *length));
DEBUGMSG(("host/hr_filesys", " %d\n", exact));
memcpy((char *) newname, (char *) vp->name, vp->namelen * sizeof(oid));
/*
* Find "next" file system entry
*/
Init_HR_FileSys();
for (;;) {
fsys_idx = Get_Next_HR_FileSys();
if (fsys_idx == -1)
break;
newname[HRFSYS_ENTRY_NAME_LENGTH] = fsys_idx;
result = snmp_oid_compare(name, *length, newname, vp->namelen + 1);
if (exact && (result == 0)) {
LowIndex = fsys_idx;
break;
}
if ((!exact && (result < 0)) &&
(LowIndex == -1 || fsys_idx < LowIndex)) {
LowIndex = fsys_idx;
#ifdef HRFS_MONOTONICALLY_INCREASING
break;
#endif
}
}
if (LowIndex == -1) {
DEBUGMSGTL(("host/hr_filesys", "... index out of range\n"));
return (MATCH_FAILED);
}
memcpy((char *) name, (char *) newname,
(vp->namelen + 1) * sizeof(oid));
*length = vp->namelen + 1;
*write_method = (WriteMethod*)0;
*var_len = sizeof(long); /* default to 'long' results */
DEBUGMSGTL(("host/hr_filesys", "... get filesys stats "));
DEBUGMSGOID(("host/hr_filesys", name, *length));
DEBUGMSG(("host/hr_filesys", "\n"));
return LowIndex;
}
oid fsys_type_id[] = { 1, 3, 6, 1, 2, 1, 25, 3, 9, 1 }; /* hrFSOther */
int fsys_type_len =
sizeof(fsys_type_id) / sizeof(fsys_type_id[0]);
/*********************
*
* System specific implementation functions
*
*********************/
u_char *
var_hrfilesys(struct variable *vp,
oid * name,
size_t * length,
int exact, size_t * var_len, WriteMethod ** write_method)
{
int fsys_idx;
static char string[1024];
char *mnt_type;
fsys_idx =
header_hrfilesys(vp, name, length, exact, var_len, write_method);
if (fsys_idx == MATCH_FAILED)
return NULL;
switch (vp->magic) {
case HRFSYS_INDEX:
long_return = fsys_idx;
return (u_char *) & long_return;
case HRFSYS_MOUNT:
strlcpy(string, HRFS_entry->HRFS_mount, sizeof(string));
*var_len = strlen(string);
return (u_char *) string;
case HRFSYS_RMOUNT:
if (Check_HR_FileSys_NFS())
strlcpy(string, HRFS_entry->HRFS_name, sizeof(string));
else
string[0] = '\0';
*var_len = strlen(string);
return (u_char *) string;
case HRFSYS_TYPE:
if (Check_HR_FileSys_NFS())
fsys_type_id[fsys_type_len - 1] = 14;
else {
/*
* Not sufficient to identity the file
* type precisely, but it's a start.
*/
#if HAVE_GETFSSTAT && !defined(MFSNAMELEN)
switch (HRFS_entry->HRFS_type) {
case MOUNT_UFS:
fsys_type_id[fsys_type_len - 1] = 3;
break;
case MOUNT_NFS:
fsys_type_id[fsys_type_len - 1] = 14;
break;
case MOUNT_HFS:
fsys_type_id[fsys_type_len - 1] = 7;
break;
case MOUNT_MFS:
fsys_type_id[fsys_type_len - 1] = 8;
break;
case MOUNT_MSDOS:
fsys_type_id[fsys_type_len - 1] = 5;
break;
case MOUNT_LFS:
fsys_type_id[fsys_type_len - 1] = 1;
break;
case MOUNT_LOFS:
fsys_type_id[fsys_type_len - 1] = 1;
break;
case MOUNT_FDESC:
fsys_type_id[fsys_type_len - 1] = 1;
break;
case MOUNT_PORTAL:
fsys_type_id[fsys_type_len - 1] = 1;
break;
case MOUNT_NULL:
fsys_type_id[fsys_type_len - 1] = 1;
break;
case MOUNT_UMAP:
fsys_type_id[fsys_type_len - 1] = 1;
break;
case MOUNT_KERNFS:
fsys_type_id[fsys_type_len - 1] = 1;
break;
case MOUNT_PROCFS:
fsys_type_id[fsys_type_len - 1] = 1;
break;
case MOUNT_AFS:
fsys_type_id[fsys_type_len - 1] = 16;
break;
case MOUNT_CD9660:
fsys_type_id[fsys_type_len - 1] = 12;
break;
case MOUNT_UNION:
fsys_type_id[fsys_type_len - 1] = 1;
break;
case MOUNT_DEVFS:
fsys_type_id[fsys_type_len - 1] = 1;
break;
#ifdef MOUNT_EXT2FS
case MOUNT_EXT2FS:
fsys_type_id[fsys_type_len - 1] = 23;
break;
#endif
#ifdef MOUNT_TFS
case MOUNT_TFS:
fsys_type_id[fsys_type_len - 1] = 15;
break;
#endif
}
#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
switch (HRFS_entry->HRFS_type) {
case MNT_AIX:
case MNT_JFS:
fsys_type_id[fsys_type_len - 1] = 3;
break;
case MNT_CDROM:
fsys_type_id[fsys_type_len - 1] = 12;
break;
#ifdef MNT_NAMEFS
case MNT_NAMEFS:
#endif
#ifdef MNT_PROCFS
case MNT_PROCFS:
#endif
case MNT_SFS:
case MNT_CACHEFS:
fsys_type_id[fsys_type_len - 1] = 1;
break;
case MNT_NFS:
case MNT_NFS3:
case MNT_AUTOFS:
fsys_type_id[fsys_type_len - 1] = 14;
break;
}
#else
mnt_type = HRFS_entry->HRFS_type;
if (mnt_type == NULL)
fsys_type_id[fsys_type_len - 1] = 2; /* unknown */
#ifdef MNTTYPE_HFS
else if (!strcmp(mnt_type, MNTTYPE_HFS))
fsys_type_id[fsys_type_len - 1] = 7;
#endif
#ifdef MNTTYPE_UFS
else if (!strcmp(mnt_type, MNTTYPE_UFS))
#if (defined(BerkelyFS) && !defined(MNTTYPE_HFS)) || defined(solaris2)
fsys_type_id[fsys_type_len - 1] = 3;
#else /* SysV */
fsys_type_id[fsys_type_len - 1] = 4; /* or 3? XXX */
#endif
#endif
#ifdef MNTTYPE_SYSV
else if (!strcmp(mnt_type, MNTTYPE_SYSV))
fsys_type_id[fsys_type_len - 1] = 4;
#endif
#ifdef MNTTYPE_PC
else if (!strcmp(mnt_type, MNTTYPE_PC))
fsys_type_id[fsys_type_len - 1] = 5;
#endif
#ifdef MNTTYPE_MSDOS
else if (!strcmp(mnt_type, MNTTYPE_MSDOS))
fsys_type_id[fsys_type_len - 1] = 5;
#endif
#ifdef MNTTYPE_FAT32
else if (!strcmp(mnt_type, MNTTYPE_FAT32))
fsys_type_id[fsys_type_len - 1] = 22;
#endif
#ifdef MNTTYPE_CDFS
else if (!strcmp(mnt_type, MNTTYPE_CDFS))
#ifdef RockRidge
fsys_type_id[fsys_type_len - 1] = 13;
#else /* ISO 9660 */
fsys_type_id[fsys_type_len - 1] = 12;
#endif
#endif
#ifdef MNTTYPE_HSFS
else if (!strcmp(mnt_type, MNTTYPE_HSFS))
fsys_type_id[fsys_type_len - 1] = 13;
#endif
#ifdef MNTTYPE_ISO9660
else if (!strcmp(mnt_type, MNTTYPE_ISO9660))
fsys_type_id[fsys_type_len - 1] = 12;
#endif
#ifdef MNTTYPE_CD9660
else if (!strcmp(mnt_type, MNTTYPE_CD9660))
fsys_type_id[fsys_type_len - 1] = 12;
#endif
#ifdef MNTTYPE_SMBFS
else if (!strcmp(mnt_type, MNTTYPE_SMBFS))
fsys_type_id[fsys_type_len - 1] = 14;
#endif
#ifdef MNTTYPE_NFS
else if (!strcmp(mnt_type, MNTTYPE_NFS))
fsys_type_id[fsys_type_len - 1] = 14;
#endif
#ifdef MNTTYPE_NFS3
else if (!strcmp(mnt_type, MNTTYPE_NFS3))
fsys_type_id[fsys_type_len - 1] = 14;
#endif
#ifdef MNTTYPE_NFS4
else if (!strcmp(mnt_type, MNTTYPE_NFS4))
fsys_type_id[fsys_type_len - 1] = 14;
#endif
#ifdef MNTTYPE_MFS
else if (!strcmp(mnt_type, MNTTYPE_MFS))
fsys_type_id[fsys_type_len - 1] = 8;
#endif
#ifdef MNTTYPE_EXT2FS
else if (!strcmp(mnt_type, MNTTYPE_EXT2FS))
fsys_type_id[fsys_type_len - 1] = 23;
#endif
#ifdef MNTTYPE_EXT3FS
else if (!strcmp(mnt_type, MNTTYPE_EXT3FS))
fsys_type_id[fsys_type_len - 1] = 23;
#endif
#ifdef MNTTYPE_NTFS
else if (!strcmp(mnt_type, MNTTYPE_NTFS))
fsys_type_id[fsys_type_len - 1] = 9;
#endif
else
fsys_type_id[fsys_type_len - 1] = 1; /* Other */
#endif /* HAVE_GETFSSTAT */
}
*var_len = sizeof(fsys_type_id);
return (u_char *) fsys_type_id;
case HRFSYS_ACCESS:
#if defined(HAVE_STATVFS) && defined(__NetBSD__)
long_return = HRFS_entry->f_flag & MNT_RDONLY ? 2 : 1;
#elif defined(HAVE_GETFSSTAT)
#if HAVE_STRUCT_STATFS_F_FLAGS
long_return = HRFS_entry->f_flags & MNT_RDONLY ? 2 : 1;
#else
long_return = HRFS_entry->f_flag & MNT_RDONLY ? 2 : 1;
#endif
#elif defined(cygwin)
long_return = 1;
#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
long_return = (HRFS_entry->HRFS_flags & MNT_READONLY) == 0 ? 1 : 2;
#else
#if HAVE_HASMNTOPT
if (hasmntopt(HRFS_entry, "ro") != NULL)
long_return = 2; /* Read Only */
else
#endif
long_return = 1; /* Read-Write */
#endif
return (u_char *) & long_return;
case HRFSYS_BOOT:
if (HRFS_entry->HRFS_mount[0] == '/' &&
HRFS_entry->HRFS_mount[1] == 0)
long_return = 1; /* root is probably bootable! */
else
long_return = 2; /* others probably aren't */
return (u_char *) & long_return;
case HRFSYS_STOREIDX:
long_return = fsys_idx + NETSNMP_MEM_TYPE_MAX;
return (u_char *) & long_return;
case HRFSYS_FULLDUMP:
return when_dumped(HRFS_entry->HRFS_name, FULL_DUMP, var_len);
case HRFSYS_PARTDUMP:
return when_dumped(HRFS_entry->HRFS_name, PART_DUMP, var_len);
default:
DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_hrfilesys\n",
vp->magic));
}
return NULL;
}
/*********************
*
* Internal implementation functions
*
*********************/
static int HRFS_index;
#ifndef HAVE_GETFSSTAT
static FILE *fp;
#endif
void
Init_HR_FileSys(void)
{
#if HAVE_GETFSSTAT
#if defined(HAVE_STATVFS) && defined(__NetBSD__)
fscount = getvfsstat(NULL, 0, ST_NOWAIT);
#else
fscount = getfsstat(NULL, 0, MNT_NOWAIT);
#endif
if (fsstats)
free((char *) fsstats);
fsstats = NULL;
fsstats = malloc(fscount * sizeof(*fsstats));
#if defined(HAVE_STATVFS) && defined(__NetBSD__)
getvfsstat(fsstats, fscount * sizeof(*fsstats), ST_NOWAIT);
#else
getfsstat(fsstats, fscount * sizeof(*fsstats), MNT_NOWAIT);
#endif
HRFS_index = 0;
#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
int ret;
uint size;
ret = 0;
size = 0;
if(aixmnt != NULL) free(aixmnt); /* something leaks, make it idiot-safe */
aixmnt = NULL;
aixcurr = NULL;
HRFS_index = 0;
ret = mntctl(MCTL_QUERY, sizeof(uint), &size);
if(ret == 0 && size > 0) {
aixmnt = malloc(size + sizeof(struct HRFS_entry));
if(aixmnt != NULL) {
HRFS_entry = (char *) aixmnt + size;
ret = mntctl(MCTL_QUERY, size, aixmnt);
HRFS_index = 1;
if(ret <= 0) {
free(aixmnt);
aixmnt = NULL;
HRFS_entry = NULL;
} else aixcurr = aixmnt;
}
}
#else
HRFS_index = 1;
if (fp != NULL)
fclose(fp);
fp = fopen(ETC_MNTTAB, "r");
if (!fp) {
netsnmp_config_error("Can't open mnttab %s\n", ETC_MNTTAB);
}
#endif
}
const char *HRFS_ignores[] = {
#ifdef MNTTYPE_IGNORE
MNTTYPE_IGNORE,
#endif
#ifdef MNTTYPE_SWAP
MNTTYPE_SWAP,
#endif
#ifdef MNTTYPE_PROC
MNTTYPE_PROC,
#endif
#ifdef MNTTYPE_PROCFS
MNTTYPE_PROCFS,
#endif
#ifdef MNTTYPE_AUTOFS
MNTTYPE_AUTOFS,
#else
"autofs",
#endif
#ifdef linux
"autofs",
"bdev",
"binfmt_misc",
"cpuset",
"debugfs",
"devfs",
"devpts",
"eventpollfs",
"futexfs",
"hugetlbfs",
"inotifyfs",
"mqueue",
"nfsd",
"pipefs",
"proc",
"ramfs",
"rootfs",
"rpc_pipefs",
"securityfs",
"shm",
"sockfs",
"sysfs",
"tmpfs",
"usbdevfs",
"usbfs",
#endif
#ifdef solaris2
"mntfs",
"proc",
"fd",
#endif
NULL
};
int
Get_Next_HR_FileSys(void)
{
#if HAVE_GETFSSTAT
if (HRFS_index >= fscount)
return -1;
HRFS_entry = fsstats + HRFS_index;
return ++HRFS_index;
#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
if(aixcurr == NULL) {
if(aixmnt != NULL) free(aixmnt);
aixmnt = NULL;
HRFS_entry = NULL;
return -1;
}
HRFS_entry->HRFS_name = vmt2dataptr(aixcurr, VMT_OBJECT);
HRFS_entry->HRFS_mount = vmt2dataptr(aixcurr, VMT_STUB);
HRFS_entry->HRFS_type = aixcurr->vmt_gfstype;
HRFS_entry->HRFS_flags = aixcurr->vmt_flags;
aixcurr = (char *) aixcurr + aixcurr->vmt_length;
if((char *) aixcurr >= (char *) HRFS_entry) aixcurr = NULL;
switch(HRFS_entry->HRFS_type) {
#ifdef MNT_NAMEFS
case MNT_NAMEFS:
#endif
#ifdef MNT_PROCFS
case MNT_PROCFS:
#endif
case MNT_SFS:
return Get_Next_HR_FileSys();
break;
}
return HRFS_index++;
#else
const char **cpp;
if (fp == NULL)
return -1;
#ifdef solaris2
if (getmntent(fp, HRFS_entry) != 0)
return -1;
#else
HRFS_entry = getmntent(fp);
if (HRFS_entry == NULL)
return -1;
#endif /* solaris2 */
for (cpp = HRFS_ignores; *cpp != NULL; ++cpp)
if (!strcmp(HRFS_entry->HRFS_type, *cpp))
return Get_Next_HR_FileSys();
/*
* Try and ensure that index values are persistent
* at least within a single run of the agent
*/
HRFS_index = se_find_value_in_slist("filesys", HRFS_entry->HRFS_name );
if (HRFS_index == SE_DNE) {
HRFS_index = se_find_free_value_in_slist("filesys");
if (HRFS_index == SE_DNE) { HRFS_index = 1; }
se_add_pair_to_slist( "filesys",
strdup( HRFS_entry->HRFS_name ), HRFS_index);
}
return HRFS_index++;
#endif /* HAVE_GETFSSTAT */
}
/*
* this function checks whether the current file system (info can be found
* in HRFS_entry) is a NFS file system
* HRFS_entry must be valid prior to calling this function
* returns 1 if NFS file system, 0 otherwise
*/
int
Check_HR_FileSys_NFS (void)
{
#if HAVE_GETFSSTAT && !defined(MFSNAMELEN)
if ((HRFS_entry->HRFS_type == MOUNT_NFS) ||
(HRFS_entry->HRFS_type == MOUNT_AFS))
#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
if(HRFS_entry->HRFS_type == MNT_NFS || HRFS_entry->HRFS_type == MNT_NFS3)
#else /* HAVE_GETFSSTAT */
if ( HRFS_entry->HRFS_type != NULL && (
#if defined(MNTTYPE_NFS)
!strcmp( HRFS_entry->HRFS_type, MNTTYPE_NFS) ||
#else
!strcmp( HRFS_entry->HRFS_type, "nfs") ||
#endif
#if defined(MNTTYPE_NFS3)
!strcmp( HRFS_entry->HRFS_type, MNTTYPE_NFS3) ||
#endif
#if defined(MNTTYPE_NFS4)
!strcmp( HRFS_entry->HRFS_type, MNTTYPE_NFS4) ||
#endif
#if defined(MNTTYPE_SMBFS)
!strcmp( HRFS_entry->HRFS_type, MNTTYPE_SMBFS) ||
#endif
#if defined(MNTTYPE_LOFS)
!strcmp( HRFS_entry->HRFS_type, MNTTYPE_LOFS) ||
#endif
#if defined(MNTTYPE_AFP)
!strcmp( HRFS_entry->HRFS_type, MNTTYPE_AFP) ||
#endif
!strcmp( HRFS_entry->HRFS_type, "cifs") ||
/*
* MVFS is Rational ClearCase's view file system
* it is similiar to NFS file systems in that it is mounted
* locally or remotely from the ClearCase server
*/
!strcmp( HRFS_entry->HRFS_type, "mvfs")))
#endif /* HAVE_GETFSSTAT */
return 1; /* NFS file system */
return 0; /* no NFS file system */
}
void
End_HR_FileSys(void)
{
#ifdef HAVE_GETFSSTAT
if (fsstats)
free((char *) fsstats);
fsstats = NULL;
#elif defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
if(aixmnt != NULL) {
free(aixmnt);
aixmnt = NULL;
aixcurr = NULL;
HRFS_entry = NULL;
}
#else
if (fp != NULL)
fclose(fp);
fp = NULL;
#endif
}
static u_char *
when_dumped(char *filesys, int level, size_t * length)
{
time_t dumpdate = 0, tmp;
FILE *dump_fp;
char line[1024];
char *cp1, *cp2, *cp3;
/*
* Look for the relevent entries in /etc/dumpdates
*
* This is complicated by the fact that disks are
* mounted using block devices, but dumps are
* done via the raw character devices.
* Thus the device names in /etc/dumpdates and
* /etc/mnttab don't match.
* These comparisons are therefore made using the
* final portion of the device name only.
*/
if (*filesys == '\0') /* No filesystem name? */
return date_n_time(NULL, length);
cp1 = strrchr(filesys, '/'); /* Find the last element of the current FS */
if (cp1 == NULL)
cp1 = filesys;
if ((dump_fp = fopen("/etc/dumpdates", "r")) == NULL)
return date_n_time(NULL, length);
while (fgets(line, sizeof(line), dump_fp) != NULL) {
cp2 = strchr(line, ' '); /* Start by looking at the device name only */
if (cp2 != NULL) {
*cp2 = '\0';
cp3 = strrchr(line, '/'); /* and find the last element */
if (cp3 == NULL)
cp3 = line;
if (strcmp(cp1, cp3) != 0) /* Wrong FS */
continue;
++cp2;
while (isspace(*cp2 & 0xFF))
++cp2; /* Now find the dump level */
if (level == FULL_DUMP) {
if (*(cp2++) != '0')
continue; /* Not interested in partial dumps */
while (isspace(*cp2 & 0xFF))
++cp2;
dumpdate = ctime_to_timet(cp2);
fclose(dump_fp);
return date_n_time(&dumpdate, length);
} else { /* Partial Dump */
if (*(cp2++) == '0')
continue; /* Not interested in full dumps */
while (isspace(*cp2 & 0xFF))
++cp2;
tmp = ctime_to_timet(cp2);
if (tmp > dumpdate)
dumpdate = tmp; /* Remember the 'latest' partial dump */
}
}
}
fclose(dump_fp);
return date_n_time(&dumpdate, length);
}
#define RAW_DEVICE_PREFIX "/dev/rdsk"
#define COOKED_DEVICE_PREFIX "/dev/dsk"
char *
cook_device(char *dev)
{
static char cooked_dev[SNMP_MAXPATH+1];
if (!strncmp(dev, RAW_DEVICE_PREFIX, strlen(RAW_DEVICE_PREFIX))) {
strlcpy(cooked_dev, COOKED_DEVICE_PREFIX, sizeof(cooked_dev));
strlcat(cooked_dev, dev + strlen(RAW_DEVICE_PREFIX),
sizeof(cooked_dev));
} else {
strlcpy(cooked_dev, dev, sizeof(cooked_dev));
}
return cooked_dev;
}
int
Get_FSIndex(char *dev)
{
int iindex;
Init_HR_FileSys();
while ((iindex = Get_Next_HR_FileSys()) != -1)
if (!strcmp(HRFS_entry->HRFS_name, cook_device(dev))) {
End_HR_FileSys();
return iindex;
}
End_HR_FileSys();
return 0;
}
long
Get_FSSize(char *dev)
{
struct HRFS_statfs statfs_buf;
Init_HR_FileSys();
while (Get_Next_HR_FileSys() != -1)
if (!strcmp(HRFS_entry->HRFS_name, cook_device(dev))) {
End_HR_FileSys();
if (HRFS_statfs(HRFS_entry->HRFS_mount, &statfs_buf) != -1)
/*
* with large file systems the following calculation produces
* an overflow:
* (statfs_buf.f_blocks*statfs_buf.f_bsize)/1024
*
* assumption: f_bsize is either 512 or a multiple of 1024
* in case of 512 (f_blocks/2) is returned
* otherwise (f_blocks*(f_bsize/1024)) is returned
*/
#if defined(solaris2) && defined(HAVE_STRUCT_STATVFS_F_FRSIZE)
return (statfs_buf.f_blocks*(statfs_buf.f_frsize/1024));
#else
if (statfs_buf.f_bsize == 512)
return (statfs_buf.f_blocks/2);
else
return (statfs_buf.f_blocks*(statfs_buf.f_bsize/1024));
#endif
else
return -1;
}
End_HR_FileSys();
return 0;
}