📄 disk.c
字号:
/* * disk.c */#include <config.h>#include <stdio.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif#if HAVE_UNISTD_H#include <unistd.h>#endif#if HAVE_FCNTL_H#include <fcntl.h>#endif#include <signal.h>#if HAVE_MACHINE_PARAM_H#include <machine/param.h>#endif#if HAVE_SYS_VMMETER_H#if !(defined(bsdi2) || defined(netbsd1))#include <sys/vmmeter.h>#endif#endif#if HAVE_SYS_CONF_H#include <sys/conf.h>#endif#if HAVE_SYS_PARAM_H#include <sys/param.h>#endif#if HAVE_ASM_PAGE_H#include <asm/page.h>#endif#if HAVE_SYS_SWAP_H#include <sys/swap.h>#endif#if HAVE_SYS_FS_H#include <sys/fs.h>#else#if HAVE_UFS_FS_H#include <ufs/fs.h>#else#ifdef HAVE_SYS_STAT_H#include <sys/stat.h>#endif#ifdef HAVE_SYS_VNODE_H#include <sys/vnode.h>#endif#ifdef HAVE_UFS_UFS_QUOTA_H#include <ufs/ufs/quota.h>#endif#ifdef HAVE_UFS_UFS_INODE_H#include <ufs/ufs/inode.h>#endif#if HAVE_UFS_FFS_FS_H#include <ufs/ffs/fs.h>#endif#endif#endif#if HAVE_MTAB_H#include <mtab.h>#endif#include <sys/stat.h>#include <errno.h>#if HAVE_SYS_STATFS_H#include <sys/statfs.h>#endif#if HAVE_SYS_STATVFS_H#include <sys/statvfs.h>#endif#if HAVE_SYS_VFS_H#include <sys/vfs.h>#endif#if (!defined(HAVE_STATVFS)) && defined(HAVE_STATFS)#if HAVE_SYS_MOUNT_H#include <sys/mount.h>#endif#if HAVE_SYS_SYSCTL_H#include <sys/sysctl.h>#endif#define statvfs statfs#endif#if HAVE_VM_VM_H#include <vm/vm.h>#endif#if HAVE_VM_SWAP_PAGER_H#include <vm/swap_pager.h>#endif#if HAVE_SYS_FIXPOINT_H#include <sys/fixpoint.h>#endif#if HAVE_MALLOC_H#include <malloc.h>#endif#if HAVE_STRING_H#include <string.h>#endif#if HAVE_FSTAB_H#include <fstab.h>#endif#if HAVE_MNTENT_H#include <mntent.h>#endif#if HAVE_SYS_MNTTAB_H#include <sys/mnttab.h>#endif#if HAVE_NETINET_IN_H#include <netinet/in.h>#endif#if TIME_WITH_SYS_TIME# ifdef WIN32# include <sys/timeb.h># else# include <sys/time.h># endif# include <time.h>#else# if HAVE_SYS_TIME_H# include <sys/time.h># else# include <time.h># endif#endif#if HAVE_WINSOCK_H#include <winsock.h>#endif#if HAVE_DMALLOC_H#include <dmalloc.h>#endif#include "mibincl.h"#include "struct.h"#include "disk.h"#include "util_funcs.h"#include "read_config.h"#include "agent_read_config.h"#include "auto_nlist.h"#if USING_UCD_SNMP_ERRORMIB_MODULE#include "errormib.h"#else#define setPerrorstatus(x) snmp_log_perror(x)#endif#include "system.h"int numdisks;struct diskpart disks[MAXDISKS];struct variable2 extensible_disk_variables[] = { {MIBINDEX, ASN_INTEGER, RONLY, var_extensible_disk, 1, {MIBINDEX}}, {ERRORNAME, ASN_OCTET_STR, RONLY, var_extensible_disk, 1, {ERRORNAME}}, {DISKDEVICE, ASN_OCTET_STR, RONLY, var_extensible_disk, 1, {DISKDEVICE}}, {DISKMINIMUM, ASN_INTEGER, RONLY, var_extensible_disk, 1, {DISKMINIMUM}}, {DISKMINPERCENT, ASN_INTEGER, RONLY, var_extensible_disk, 1, {DISKMINPERCENT}}, {DISKTOTAL, ASN_INTEGER, RONLY, var_extensible_disk, 1, {DISKTOTAL}}, {DISKAVAIL, ASN_INTEGER, RONLY, var_extensible_disk, 1, {DISKAVAIL}}, {DISKUSED, ASN_INTEGER, RONLY, var_extensible_disk, 1, {DISKUSED}}, {DISKPERCENT, ASN_INTEGER, RONLY, var_extensible_disk, 1, {DISKPERCENT}}, {DISKPERCENTNODE, ASN_INTEGER, RONLY, var_extensible_disk, 1, {DISKPERCENTNODE}}, {ERRORFLAG, ASN_INTEGER, RONLY, var_extensible_disk, 1, {ERRORFLAG }}, {ERRORMSG, ASN_OCTET_STR, RONLY, var_extensible_disk, 1, {ERRORMSG }}};/* Define the OID pointer to the top of the mib tree that we're registering underneath */oid disk_variables_oid[] = { EXTENSIBLEMIB,DISKMIBNUM,1 };void init_disk(void){ /* register ourselves with the agent to handle our mib tree */ REGISTER_MIB("ucd-snmp/disk", extensible_disk_variables, variable2, \ disk_variables_oid); snmpd_register_config_handler("disk", disk_parse_config, disk_free_config, "path [ minspace | minpercent% ]");}void disk_free_config (void) { int i; numdisks = 0; for(i=0;i<MAXDISKS;i++) { /* init/erase disk db */ disks[i].device[0] = 0; disks[i].path[0] = 0; disks[i].minimumspace = -1; disks[i].minpercent = -1; }}void disk_parse_config(const char *token, char *cptr){#if HAVE_GETMNTENT#if HAVE_SYS_MNTTAB_H struct mnttab mnttab;#else struct mntent *mntent;#endif FILE *mntfp;#else#if HAVE_FSTAB_H struct fstab *fstab; struct stat stat1;#endif#endif char tmpbuf[1024];#if defined(HAVE_GETMNTENT) && !defined(HAVE_SETMNTENT) int i;#endif#if HAVE_FSTAB_H || HAVE_GETMNTENT if (numdisks == MAXDISKS) { config_perror("Too many disks specified."); sprintf(tmpbuf,"\tignoring: %s",cptr); config_perror(tmpbuf); } else { /* read disk path (eg, /1 or /usr) */ copy_word(cptr,disks[numdisks].path); cptr = skip_not_white(cptr); cptr = skip_white(cptr); /* read optional minimum disk usage spec */ if (cptr != NULL) { if (strchr(cptr, '%') == 0) { disks[numdisks].minimumspace = atoi(cptr); disks[numdisks].minpercent = -1; } else { disks[numdisks].minimumspace = -1; disks[numdisks].minpercent = atoi(cptr); } } else { disks[numdisks].minimumspace = DEFDISKMINIMUMSPACE; disks[numdisks].minpercent = -1; } /* find the device associated with the directory */#if HAVE_GETMNTENT#if HAVE_SETMNTENT mntfp = setmntent(ETC_MNTTAB, "r"); disks[numdisks].device[0] = 0; while ((mntent = getmntent (mntfp))) if (strcmp (disks[numdisks].path, mntent->mnt_dir) == 0) { copy_word (mntent->mnt_fsname, disks[numdisks].device); DEBUGMSGTL(("ucd-snmp/disk", "Disk: %s\n",mntent->mnt_fsname)); break; } else { DEBUGMSGTL(("ucd-snmp/disk", " %s != %s\n", disks[numdisks].path, mntent->mnt_dir)); } endmntent(mntfp); if (disks[numdisks].device[0] != 0) { /* dummy clause for else below */ numdisks += 1; /* but inc numdisks here after test */ }#else /* getmentent but not setmntent */ mntfp = fopen (ETC_MNTTAB, "r"); while ((i = getmntent (mntfp, &mnttab)) == 0) if (strcmp (disks[numdisks].path, mnttab.mnt_mountp) == 0) break; else { DEBUGMSGTL(("ucd-snmp/disk", " %s != %s\n", disks[numdisks].path, mnttab.mnt_mountp)); } fclose (mntfp); if (i == 0) { copy_word (mnttab.mnt_special, disks[numdisks].device); numdisks += 1; }#endif /* HAVE_SETMNTENT */#else#if HAVE_FSTAB_H stat(disks[numdisks].path,&stat1); setfsent(); if ((fstab = getfsfile(disks[numdisks].path))) { copy_word(fstab->fs_spec,disks[numdisks].device); numdisks += 1; }#endif#endif else { sprintf(tmpbuf, "Couldn't find device for disk %s", disks[numdisks].path); config_pwarn(tmpbuf); disks[numdisks].minimumspace = -1; disks[numdisks].minpercent = -1; disks[numdisks].path[0] = 0; }#if HAVE_FSTAB_H endfsent();#endif }#else config_perror("'disk' checks not supported on this architecture.");#endif}/* var_extensible_disk(... 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 */u_char *var_extensible_disk(struct variable *vp, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ int percent, iserror, disknum=0;#if !defined(HAVE_SYS_STATVFS_H) && !defined(HAVE_STATFS) double totalblks, free, used, avail, availblks;#else static long avail;#ifdef STRUCT_STATVFS_HAS_F_FILES int percent_inode;#endif#endif static long long_ret; static char errmsg[300];#if defined(HAVE_STATVFS) || defined(HAVE_STATFS)#ifdef STAT_STATFS_FS_DATA struct fs_data fsd; struct { u_int f_blocks, f_bfree, f_bavail; } vfs;#else struct statvfs vfs;#endif#else#if HAVE_FSTAB_H int file; union { struct fs iu_fs; char dummy[SBSIZE]; } sb;#define filesys sb.iu_fs#endif#endif if (header_simple_table(vp,name,length,exact,var_len,write_method,numdisks)) return(NULL); disknum = name[*length - 1] - 1; switch (vp->magic) { case MIBINDEX: long_ret = disknum+1; return((u_char *) (&long_ret)); case ERRORNAME: /* DISKPATH */ *var_len = strlen(disks[disknum].path); return((u_char *) disks[disknum].path); case DISKDEVICE: *var_len = strlen(disks[disknum].device); return((u_char *) disks[disknum].device); case DISKMINIMUM: long_ret = disks[disknum].minimumspace; return((u_char *) (&long_ret)); case DISKMINPERCENT: long_ret = disks[disknum].minpercent; return((u_char *) (&long_ret)); }#if defined(HAVE_SYS_STATVFS_H) || defined(HAVE_STATFS)#ifdef STAT_STATFS_FS_DATA if (statvfs (disks[disknum].path, &fsd) == -1) {#else if (statvfs (disks[disknum].path, &vfs) == -1) {#endif snmp_log(LOG_ERR,"Couldn't open device %s\n",disks[disknum].device); setPerrorstatus("statvfs dev/disk"); return NULL; }#ifdef STAT_STATFS_FS_DATA vfs.f_blocks = fsd.fd_btot; vfs.f_bfree = fsd.fd_bfree; vfs.f_bavail = fsd.fd_bfreen;#endif#if defined(HAVE_ODS) vfs.f_blocks = vfs.f_spare[0]; vfs.f_bfree = vfs.f_spare[1]; vfs.f_bavail = vfs.f_spare[2];#endif percent = vfs.f_bavail <= 0 ? 100 : (int) ((double) (vfs.f_blocks - vfs.f_bfree) / (double) (vfs.f_blocks - (vfs.f_bfree - vfs.f_bavail)) * 100.0 + 0.5); avail = vfs.f_bavail;#ifdef STRUCT_STATVFS_HAS_F_FRSIZE if (vfs.f_frsize > 255) avail = avail * (vfs.f_frsize / 1024);#endif iserror = (disks[disknum].minimumspace >= 0 ? avail < disks[disknum].minimumspace : 100-percent <= disks[disknum].minpercent) ? 1 : 0;#ifdef STRUCT_STATVFS_HAS_F_FILES percent_inode = vfs.f_favail <= 0 ? 100 : (int) ((double) (vfs.f_files - vfs.f_ffree) / (double) (vfs.f_files - (vfs.f_ffree - vfs.f_favail)) * 100.0 + 0.5);#endif switch (vp->magic) { case DISKTOTAL: long_ret = vfs.f_blocks;#ifdef STRUCT_STATVFS_HAS_F_FRSIZE if (vfs.f_frsize > 255) long_ret = long_ret * (vfs.f_frsize / 1024);#endif return((u_char *) (&long_ret)); case DISKAVAIL: return((u_char *) (&avail)); case DISKUSED: long_ret = (vfs.f_blocks - vfs.f_bfree);#ifdef STRUCT_STATVFS_HAS_F_FRSIZE if (vfs.f_frsize > 255) long_ret = long_ret * (vfs.f_frsize / 1024);#endif return((u_char *) (&long_ret)); case DISKPERCENT: long_ret = percent; return ((u_char *) (&long_ret));#ifdef STRUCT_STATVFS_HAS_F_FILES case DISKPERCENTNODE: long_ret = percent_inode; return ((u_char *) (&long_ret));#endif case ERRORFLAG: long_ret = iserror; return((u_char *) (&long_ret)); case ERRORMSG: if (iserror) { if (disks[disknum].minimumspace >= 0) sprintf(errmsg,"%s: less than %d free (= %d)",disks[disknum].path, disks[disknum].minimumspace, (int) avail); else sprintf(errmsg,"%s: less than %d%% free (= %d%%)",disks[disknum].path, disks[disknum].minpercent, percent); } else errmsg[0] = 0; *var_len = strlen(errmsg); return((u_char *) (errmsg)); }#else#if HAVE_FSTAB_H /* read the disk information */ if ((file = open(disks[disknum].device,0)) < 0) { snmp_log(LOG_ERR,"Couldn't open device %s\n",disks[disknum].device); setPerrorstatus("open dev/disk"); return(NULL); } lseek(file, (long) (SBLOCK * DEV_BSIZE), 0); if (read(file,(char *) &filesys, SBSIZE) != SBSIZE) { setPerrorstatus("open dev/disk"); snmp_log(LOG_ERR,"Error reading device %s\n",disks[disknum].device); close(file); return(NULL); } close(file); totalblks = filesys.fs_dsize; free = filesys.fs_cstotal.cs_nbfree * filesys.fs_frag + filesys.fs_cstotal.cs_nffree; used = totalblks - free; availblks = totalblks * (100 - filesys.fs_minfree) / 100; avail = availblks > used ? availblks - used : 0; percent = availblks == 0 ? 100 : (int) ((double) used / (double) totalblks * 100.0 + 0.5); iserror = (disks[disknum].minimumspace >= 0 ? avail * filesys.fs_fsize / 1024 < disks[disknum].minimumspace : 100-percent <= disks[disknum].minpercent) ? 1 : 0; switch (vp->magic) { case DISKTOTAL: long_ret = (totalblks * filesys.fs_fsize / 1024); return((u_char *) (&long_ret)); case DISKAVAIL: long_ret = avail * filesys.fs_fsize/1024; return((u_char *) (&long_ret)); case DISKUSED: long_ret = used * filesys.fs_fsize/1024; return((u_char *) (&long_ret)); case DISKPERCENT: long_ret = percent; return ((u_char *) (&long_ret)); case ERRORFLAG: long_ret = iserror; return((u_char *) (&long_ret)); case ERRORMSG: if (iserror) if (disks[disknum].minimumspace >= 0) sprintf(errmsg,"%s: less than %d free (= %d)",disks[disknum].path, disks[disknum].minimumspace, avail * filesys.fs_fsize/1024); else sprintf(errmsg,"%s: less than %d%% free (= %d%%)",disks[disknum].path, disks[disknum].minpercent, percent); else errmsg[0] = 0; *var_len = strlen(errmsg); return((u_char *) (errmsg)); }#endif#endif return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -