blob: 63a853869603a98ead32a09cc243faa270baa0bd [file] [log] [blame]
#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/fsys.h>
#include <stdio.h>
#if HAVE_MNTENT_H
#include <mntent.h>
#endif
#if HAVE_SYS_MNTTAB_H
#include <sys/mnttab.h>
#endif
#if HAVE_SYS_VFS_H
#include <sys/vfs.h>
#endif
#if HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#if HAVE_SYS_MOUNT_H
#include <sys/mount.h>
#endif
#if HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
#if HAVE_SYS_STATVFS_H
#include <sys/statvfs.h>
#endif
#ifdef solaris2
#define _NETSNMP_GETMNTENT_TWO_ARGS 1
#else
#undef _NETSNMP_GETMNTENT_TWO_ARGS
#endif
/*
* Handle naming differences between getmntent() APIs
*/
#ifdef _NETSNMP_GETMNTENT_TWO_ARGS
/* Two-argument form (Solaris) */
#define NSFS_MNTENT struct mnttab
#define NSFS_PATH mnt_mountp
#define NSFS_DEV mnt_special
#define NSFS_TYPE mnt_fstype
#define NSFS_STATFS statvfs
#define NSFS_SIZE f_frsize
#else
/* One-argument form (everything else?) */
#define NSFS_MNTENT struct mntent
#define NSFS_PATH mnt_dir
#define NSFS_DEV mnt_fsname
#define NSFS_TYPE mnt_type
#define NSFS_STATFS statfs
#define NSFS_SIZE f_bsize
#endif
int
_fsys_remote( char *device, int type )
{
if (( type == NETSNMP_FS_TYPE_NFS) ||
( type == NETSNMP_FS_TYPE_AFS))
return 1;
else
return 0;
}
int
_fsys_type( char *typename )
{
DEBUGMSGTL(("fsys:type", "Classifying %s\n", typename));
if ( !typename || *typename=='\0' )
return NETSNMP_FS_TYPE_UNKNOWN;
#include "mnttypes.h"
else if ( !strcmp(typename, MNTTYPE_FFS) )
return NETSNMP_FS_TYPE_BERKELEY;
else if ( !strcmp(typename, MNTTYPE_UFS) )
return _NETSNMP_FS_TYPE_UFS; /* either N_FS_TYPE_BERKELEY or N_FS_TYPE_SYSV */
else if ( !strcmp(typename, MNTTYPE_SYSV) )
return NETSNMP_FS_TYPE_SYSV;
else if ( !strcmp(typename, MNTTYPE_PC) ||
!strcmp(typename, MNTTYPE_MSDOS) )
return NETSNMP_FS_TYPE_FAT;
else if ( !strcmp(typename, MNTTYPE_HFS) )
return NETSNMP_FS_TYPE_HFS;
else if ( !strcmp(typename, MNTTYPE_MFS) )
return NETSNMP_FS_TYPE_MFS;
else if ( !strcmp(typename, MNTTYPE_NTFS) )
return NETSNMP_FS_TYPE_NTFS;
else if ( !strcmp(typename, MNTTYPE_ISO9660) ||
!strcmp(typename, MNTTYPE_CD9660) )
return NETSNMP_FS_TYPE_ISO9660;
else if ( !strcmp(typename, MNTTYPE_CDFS) )
return _NETSNMP_FS_TYPE_CDFS; /* either N_FS_TYPE_ISO9660 or N_FS_TYPE_ROCKRIDGE */
else if ( !strcmp(typename, MNTTYPE_HSFS) )
return NETSNMP_FS_TYPE_ROCKRIDGE;
else if ( !strcmp(typename, MNTTYPE_NFS) ||
!strcmp(typename, MNTTYPE_NFS3) ||
!strcmp(typename, MNTTYPE_NFS4) ||
!strcmp(typename, MNTTYPE_CIFS) || /* i.e. SMB - ?? */
!strcmp(typename, MNTTYPE_SMBFS) /* ?? */ )
return NETSNMP_FS_TYPE_NFS;
else if ( !strcmp(typename, MNTTYPE_NCPFS) )
return NETSNMP_FS_TYPE_NETWARE;
else if ( !strcmp(typename, MNTTYPE_AFS) )
return NETSNMP_FS_TYPE_AFS;
else if ( !strcmp(typename, MNTTYPE_EXT2) ||
!strcmp(typename, MNTTYPE_EXT3) ||
!strcmp(typename, MNTTYPE_EXT4) ||
!strcmp(typename, MNTTYPE_EXT2FS) ||
!strcmp(typename, MNTTYPE_EXT3FS) ||
!strcmp(typename, MNTTYPE_EXT4FS) )
return NETSNMP_FS_TYPE_EXT2;
else if ( !strcmp(typename, MNTTYPE_FAT32) ||
!strcmp(typename, MNTTYPE_VFAT) )
return NETSNMP_FS_TYPE_FAT32;
/*
* The following code covers selected filesystems
* which are not covered by the HR-TYPES enumerations,
* but should still be monitored.
* These are all mapped into type "other"
*
* (The systems listed are not fixed in stone,
* but are simply here to illustrate the principle!)
*/
else if ( !strcmp(typename, MNTTYPE_MVFS) ||
!strcmp(typename, MNTTYPE_TMPFS) ||
!strcmp(typename, MNTTYPE_GFS) ||
!strcmp(typename, MNTTYPE_GFS2) ||
!strcmp(typename, MNTTYPE_XFS) ||
!strcmp(typename, MNTTYPE_JFS) ||
!strcmp(typename, MNTTYPE_VXFS) ||
!strcmp(typename, MNTTYPE_REISERFS) ||
!strcmp(typename, MNTTYPE_OCFS2) ||
!strcmp(typename, MNTTYPE_CVFS) ||
!strcmp(typename, MNTTYPE_SIMFS) ||
!strcmp(typename, MNTTYPE_BTRFS) ||
!strcmp(typename, MNTTYPE_ZFS) ||
!strcmp(typename, MNTTYPE_ACFS) ||
!strcmp(typename, MNTTYPE_LOFS))
return NETSNMP_FS_TYPE_OTHER;
/*
* All other types are silently skipped
*/
else
return NETSNMP_FS_TYPE_IGNORE;
}
void
netsnmp_fsys_arch_init( void )
{
return;
}
void
netsnmp_fsys_arch_load( void )
{
FILE *fp=NULL;
#ifdef _NETSNMP_GETMNTENT_TWO_ARGS
struct mnttab mtmp;
struct mnttab *m = &mtmp;
#else
struct mntent *m;
#endif
struct NSFS_STATFS stat_buf;
netsnmp_fsys_info *entry;
char tmpbuf[1024];
/*
* Retrieve information about the currently mounted filesystems...
*/
fp = fopen( ETC_MNTTAB, "r" ); /* OR setmntent()?? */
if ( !fp ) {
snprintf( tmpbuf, sizeof(tmpbuf), "Cannot open %s", ETC_MNTTAB );
snmp_log_perror( tmpbuf );
return;
}
/*
* ... and insert this into the filesystem container.
*/
while
#ifdef _NETSNMP_GETMNTENT_TWO_ARGS
((getmntent(fp, m)) == 0 )
#else
((m = getmntent(fp)) != NULL )
#endif
{
entry = netsnmp_fsys_by_path( m->NSFS_PATH, NETSNMP_FS_FIND_CREATE );
if (!entry) {
continue;
}
strlcpy(entry->path, m->NSFS_PATH, sizeof(entry->path));
strlcpy(entry->device, m->NSFS_DEV, sizeof(entry->device));
entry->type = _fsys_type(m->NSFS_TYPE);
if (!(entry->type & _NETSNMP_FS_TYPE_SKIP_BIT))
entry->flags |= NETSNMP_FS_FLAG_ACTIVE;
if ( _fsys_remote( entry->device, entry->type ))
entry->flags |= NETSNMP_FS_FLAG_REMOTE;
#if HAVE_HASMNTOPT
if (hasmntopt( m, "ro" ))
entry->flags |= NETSNMP_FS_FLAG_RONLY;
#endif
/*
* The root device is presumably bootable.
* Other partitions probably aren't!
*
* XXX - what about /boot ??
*/
if ((entry->path[0] == '/') &&
(entry->path[1] == '\0'))
entry->flags |= NETSNMP_FS_FLAG_BOOTABLE;
/*
* XXX - identify removeable disks
*/
/*
* Optionally skip retrieving statistics for remote mounts
*/
if ( (entry->flags & NETSNMP_FS_FLAG_REMOTE) &&
netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES))
continue;
#ifdef irix6
if ( NSFS_STATFS( entry->path, &stat_buf, sizeof(struct statfs), 0) < 0 )
#else
if ( NSFS_STATFS( entry->path, &stat_buf ) < 0 )
#endif
{
snprintf( tmpbuf, sizeof(tmpbuf), "Cannot statfs %s", entry->path );
snmp_log_perror( tmpbuf );
continue;
}
entry->units = stat_buf.NSFS_SIZE;
entry->size = stat_buf.f_blocks;
entry->used = (stat_buf.f_blocks - stat_buf.f_bfree);
/* entry->avail is currently unsigned, so protect against negative
* values!
* This should be changed to a signed field.
*/
if (stat_buf.f_bavail < 0)
entry->avail = 0;
else
entry->avail = stat_buf.f_bavail;
entry->inums_total = stat_buf.f_files;
entry->inums_avail = stat_buf.f_ffree;
}
fclose( fp );
}