From owner-p4-projects@FreeBSD.ORG Thu Jul 14 14:35:08 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id E293D16A420; Thu, 14 Jul 2005 14:35:07 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id BBD7C16A41C for ; Thu, 14 Jul 2005 14:35:07 +0000 (GMT) (envelope-from soc-victor@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 64CA643D45 for ; Thu, 14 Jul 2005 14:35:07 +0000 (GMT) (envelope-from soc-victor@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j6EEZ7iA083477 for ; Thu, 14 Jul 2005 14:35:07 GMT (envelope-from soc-victor@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j6EEZ7Nv083474 for perforce@freebsd.org; Thu, 14 Jul 2005 14:35:07 GMT (envelope-from soc-victor@freebsd.org) Date: Thu, 14 Jul 2005 14:35:07 GMT Message-Id: <200507141435.j6EEZ7Nv083474@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to soc-victor@freebsd.org using -f From: soc-victor To: Perforce Change Reviews Cc: Subject: PERFORCE change 80161 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jul 2005 14:35:08 -0000 http://perforce.freebsd.org/chv.cgi?CH=80161 Change 80161 by soc-victor@soc-victor_82.76.158.176 on 2005/07/14 14:34:47 First version of the hrStorageTable, containing only swap details (per swap device). Also it contains the persistent map (per agent lifetime) for hrStorageTable index. Next changeset will add some VM data and FS storage info. Affected files ... .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile#5 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_scalars.c#4 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c#4 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.h#4 edit Differences ... ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile#5 (text+ko) ==== @@ -6,10 +6,11 @@ CONTRIB=${.CURDIR}/../../../../contrib/bsnmp MOD= hostres -SRCS= hostres_snmp.c hostres_scalars.c +SRCS= hostres_snmp.c hostres_scalars.c \ + hostres_storage_tbl.c WARNS?= 6 #Not having NDEBUG defined will enable assertions and a lot of output on stderr -CFLAGS+= -DNDEBUG +#CFLAGS+= -DNDEBUG XSYM= host hrStorageOther hrStorageRam hrStorageVirtualMemory \ hrStorageFixedDisk hrStorageRemovableDisk hrStorageFloppyDisk \ hrStorageCompactDisc hrStorageRamDisk hrStorageFlashMemory \ ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_scalars.c#4 (text+ko) ==== @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Host Resource MIB scalars implementation for SNMPd. + * Host Resources MIB scalars implementation for SNMPd. */ #include "hostres_snmp.h" #include "hostres_tree.h" @@ -208,17 +208,17 @@ switch (value->var.subs[sub - 1]) { case LEAF_hrSystemDate: { if ( string_save(value, ctx, 8, - &hostres_ctx_g.time_to_set ) == SNMP_ERR_NOERROR + &hrState_g.time_to_set ) == SNMP_ERR_NOERROR || string_save(value, ctx, 11, - &hostres_ctx_g.time_to_set ) == SNMP_ERR_NOERROR + &hrState_g.time_to_set ) == SNMP_ERR_NOERROR ) { - if( OS_checkSystemDateInput( hostres_ctx_g.time_to_set, - &hostres_ctx_g.timeval_to_set) != 0 ) { + if( OS_checkSystemDateInput( hrState_g.time_to_set, + &hrState_g.timeval_to_set) != 0 ) { HR_DPRINTF((stderr, "Parse for '%s' failed as DateAndTime \n", - hostres_ctx_g.time_to_set)); + hrState_g.time_to_set)); return (SNMP_ERR_GENERR); } } @@ -239,9 +239,9 @@ switch (value->var.subs[sub - 1]) { case LEAF_hrSystemDate: { HR_DPRINTF((stderr, "SNMP_OP_ROLLBACK for LEAF_hrSystemDate\n")); - string_rollback(ctx, &hostres_ctx_g.time_to_set); - hostres_ctx_g.timeval_to_set.tv_sec = 0; - hostres_ctx_g.timeval_to_set.tv_usec = 0; + string_rollback(ctx, &hrState_g.time_to_set); + hrState_g.timeval_to_set.tv_sec = 0; + hrState_g.timeval_to_set.tv_usec = 0; return (SNMP_ERR_NOERROR); } @@ -261,7 +261,7 @@ HR_DPRINTF((stderr, "SNMP_OP_COMMIT for LEAF_hrSystemDate\n")); string_commit(ctx); - if( OS_setSystemDate(&hostres_ctx_g.timeval_to_set) != 0 ) { + if( OS_setSystemDate(&hrState_g.timeval_to_set) != 0 ) { HR_DPRINTF((stderr, "SNMP_OP_COMMIT FAILEDfor LEAF_hrSystemDate\n")); return (SNMP_ERR_GENERR); @@ -346,7 +346,7 @@ struct timeval right_now = {0,0}; - if( hostres_ctx_g.kernel_boot == 0 ) { + if( hrState_g.kernel_boot == 0 ) { /*first time, do the sysctl*/ @@ -363,7 +363,7 @@ kernel_boot_timestamp.tv_sec, kernel_boot_timestamp.tv_usec)); - hostres_ctx_g.kernel_boot = (kernel_boot_timestamp.tv_sec * 100) + + hrState_g.kernel_boot = (kernel_boot_timestamp.tv_sec * 100) + (kernel_boot_timestamp.tv_usec / 10000); } @@ -374,7 +374,7 @@ return ( (right_now.tv_sec * 100) + (right_now.tv_usec / 10000) - - hostres_ctx_g. kernel_boot ); + hrState_g. kernel_boot ); @@ -427,7 +427,7 @@ OS_getSystemInitialLoadParameters(void){ - if( strlen(hostres_ctx_g.k_boot_line) == 0) { + if( strlen(hrState_g.k_boot_line) == 0) { int mib[2]={ CTL_KERN, KERN_BOOTFILE }; char *buf = NULL; size_t buf_len = 0; @@ -447,11 +447,11 @@ return (NULL); /*error*/ } - (void)strncpy(hostres_ctx_g.k_boot_line, buf, 127); - HR_DPRINTF((stderr, "Got kernel boot file: %s\n", hostres_ctx_g.k_boot_line)); + (void)strncpy(hrState_g.k_boot_line, buf, 127); + HR_DPRINTF((stderr, "Got kernel boot file: %s\n", hrState_g.k_boot_line)); free(buf); } - return ((u_char*)&hostres_ctx_g.k_boot_line[0]); + return ((u_char*)&hrState_g.k_boot_line[0]); } @@ -460,14 +460,14 @@ int user_counter = 0; struct utmp utmp_entry; struct passwd *pw; - if( hostres_ctx_g.utmp_fp == (FILE*)NULL ) { + if( hrState_g.utmp_fp == (FILE*)NULL ) { assert(0); return (-1); /*error*/ } /*start with the begining of the utmp file*/ - rewind(hostres_ctx_g.utmp_fp); + rewind(hrState_g.utmp_fp); - while (fread(&utmp_entry, sizeof(utmp_entry), 1, hostres_ctx_g.utmp_fp) == 1 ) { + while (fread(&utmp_entry, sizeof(utmp_entry), 1, hrState_g.utmp_fp) == 1 ) { if (utmp_entry.ut_name[0] && utmp_entry.ut_line[0]) { if( (pw = getpwnam(utmp_entry.ut_name)) == NULL ) { continue; @@ -482,12 +482,12 @@ int OS_getSystemProcesses(void) { int proc_count = 0; - if( hostres_ctx_g.kd == (kvm_t*)NULL ) { + if( hrState_g.kd == (kvm_t*)NULL ) { assert(0); return (-1); /*error*/ } - if( kvm_getprocs(hostres_ctx_g.kd, KERN_PROC_PROC, 0, &proc_count) == NULL ) { + if( kvm_getprocs(hrState_g.kd, KERN_PROC_PROC, 0, &proc_count) == NULL ) { syslog(LOG_ERR, "kvm_getprocs failed: %m "); return (-1);/*error*/ } @@ -496,34 +496,34 @@ int OS_getSystemMaxProcesses(void) { - if( hostres_ctx_g.max_proc == 0 ) { + if( hrState_g.max_proc == 0 ) { int mib[2] = {CTL_KERN, KERN_MAXPROC}; size_t len = 0; - len = sizeof(hostres_ctx_g.max_proc); - if(sysctl(mib, 2, &hostres_ctx_g.max_proc, &len, NULL, 0) == -1) { + len = sizeof(hrState_g.max_proc); + if(sysctl(mib, 2, &hrState_g.max_proc, &len, NULL, 0) == -1) { syslog(LOG_ERR, "sysctl KERN_MAXPROC failed: %m "); return (-1); /*error*/ } - HR_DPRINTF((stderr, "Got kernel maxporc: %d\n",hostres_ctx_g.max_proc)); + HR_DPRINTF((stderr, "Got kernel maxporc: %d\n",hrState_g.max_proc)); } - return (hostres_ctx_g.max_proc); + return (hrState_g.max_proc); } uint32_t OS_getMemorySize(void) { - if(hostres_ctx_g.phys_mem_size == 0) { + if(hrState_g.phys_mem_size == 0) { int mib[2] = { CTL_HW, HW_PHYSMEM }; - size_t len = sizeof(hostres_ctx_g.phys_mem_size); - if (sysctl(mib, 2, &hostres_ctx_g.phys_mem_size, &len, NULL, 0) == -1) { + size_t len = sizeof(hrState_g.phys_mem_size); + if (sysctl(mib, 2, &hrState_g.phys_mem_size, &len, NULL, 0) == -1) { syslog(LOG_ERR, "sysctl({ CTL_HW, HW_PHYSMEM }) failed: %m "); return 0; /*error*/ } - hostres_ctx_g.phys_mem_size = hostres_ctx_g.phys_mem_size / 1024; + hrState_g.phys_mem_size = hrState_g.phys_mem_size / 1024; } - return (hostres_ctx_g.phys_mem_size); + return (hrState_g.phys_mem_size); } ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c#4 (text+ko) ==== @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Host Resource MIB implementation for SNMPd. + * Host Resources MIB implementation for SNMPd. */ #include "hostres_snmp.h" #include "hostres_oid.h" @@ -36,7 +36,9 @@ #include #include #include +#include + /*internal id got after we'll register this module with the agent */ static u_int host_registration_id = 0; @@ -49,7 +51,7 @@ const struct asn_oid oid_host = OIDX_host; /*see the generated file hostres_oid.h*/ -hostres_ctx_type hostres_ctx_g; +struct hostres_state hrState_g; /* HOST RESOURCES mib module initialization hook. @@ -60,24 +62,24 @@ hostres_module = mod; - hostres_ctx_g.utmp_fp = (FILE*)NULL; - hostres_ctx_g.kd = (kvm_t*)NULL; - hostres_ctx_g.kernel_boot = 0; + hrState_g.utmp_fp = (FILE*)NULL; + hrState_g.kd = (kvm_t*)NULL; + hrState_g.kernel_boot = 0; - memset(&hostres_ctx_g.k_boot_line[0], + memset(&hrState_g.k_boot_line[0], '\0', - sizeof(hostres_ctx_g.k_boot_line)); + sizeof(hrState_g.k_boot_line)); - hostres_ctx_g.max_proc = 0; + hrState_g.max_proc = 0; - hostres_ctx_g.phys_mem_size = 0; + hrState_g.phys_mem_size = 0; - if( ( hostres_ctx_g.utmp_fp = fopen(_PATH_UTMP, "r") ) == (FILE*)NULL) { + if( ( hrState_g.utmp_fp = fopen(_PATH_UTMP, "r") ) == (FILE*)NULL) { syslog(LOG_ERR, "fopen(%s) failed: %m ", (const char*)_PATH_UTMP); return (-1); /*error*/ } - if( ( hostres_ctx_g.kd = + if( ( hrState_g.kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open")) == (kvm_t*)NULL ) { syslog(LOG_ERR, "kvm_open failed: %m "); @@ -85,7 +87,12 @@ } + hrState_g.hr_tick = 0; + + init_hrStorage_tbl_v(); + HR_DPRINTF((stderr, "[%s] done.\n", __func__)); + return (0); } @@ -98,32 +105,34 @@ int hostres_fini(void) { /* here I free the resources used by this module*/ - if( hostres_ctx_g.utmp_fp != (FILE*)NULL ) { - if( fclose(hostres_ctx_g.utmp_fp) != 0 ) { + if( hrState_g.utmp_fp != (FILE*)NULL ) { + if( fclose(hrState_g.utmp_fp) != 0 ) { syslog(LOG_ERR, "fclose failed: %m "); return (-1); /*error*/ } - hostres_ctx_g.utmp_fp = (FILE*)NULL; + hrState_g.utmp_fp = (FILE*)NULL; } - if( hostres_ctx_g.kd != (kvm_t*)NULL ) { - if( kvm_close(hostres_ctx_g.kd) != 0 ) { + if( hrState_g.kd != (kvm_t*)NULL ) { + if( kvm_close(hrState_g.kd) != 0 ) { syslog(LOG_ERR, "kvm_close failed: %m "); return (-1); /*error*/ } - hostres_ctx_g.kd = (kvm_t*)NULL; + hrState_g.kd = (kvm_t*)NULL; } - hostres_ctx_g.kernel_boot = 0; + hrState_g.kernel_boot = 0; - memset(&hostres_ctx_g.k_boot_line[0], + memset(&hrState_g.k_boot_line[0], '\0', - sizeof(hostres_ctx_g.k_boot_line)); + sizeof(hrState_g.k_boot_line)); - hostres_ctx_g.max_proc = 0; + hrState_g.max_proc = 0; - hostres_ctx_g.phys_mem_size = 0; - + hrState_g.phys_mem_size = 0; + + fini_hrStorage_tbl_v(); + if( host_registration_id > 0){ or_unregister(host_registration_id); } @@ -137,6 +146,11 @@ */ static void hostres_idle_v(void) { + if ( (time(NULL) - hrState_g.hrStorage_tbl_age) > 7 ) { + HR_DPRINTF((stderr, " %s: need refresh\n ",__func__)); + refresh_hrStorage_tbl_v(); + } + /*nothing iteresting here for the time being*/ HR_DPRINTF((stderr, "[%s] done.\n ", __func__)); } @@ -207,14 +221,6 @@ Next items are not implemented yet. Once one of them is implemented it will be moved into its own C file */ -int op_hrStorageTable(struct snmp_context *ctx __unused, - struct snmp_value *value __unused, - u_int sub __unused, - u_int iidx __unused, - enum snmp_op curr_op __unused) -{ - return (SNMP_ERR_NOSUCHNAME); -} int op_hrDeviceTable(struct snmp_context *ctx __unused, struct snmp_value *value __unused, ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.h#4 (text+ko) ==== @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Host Resource MIB for SNMPd. + * Host Resources MIB for SNMPd. */ #ifndef __HOSTRES_SNMP_H_INCLUDED__ #define __HOSTRES_SNMP_H_INCLUDED__ @@ -38,6 +38,7 @@ #include /*for kvm_open & friends*/ #include #include /*for struct timeval*/ +#include /*for SLIST, TAILQ & friends*/ /*a debug macro*/ @@ -47,10 +48,10 @@ fprintf ARGS; \ } while (0) #else -#define HR_DPRINTF(args) +#define HR_DPRINTF(ARGS) #endif /*NDEBUG*/ -typedef struct hostres_ctx_struct{ +struct hostres_state { FILE *utmp_fp; /*file pointer to keep an open instance of utmp*/ kvm_t *kd; /*kernel descriptor*/ uint32_t kernel_boot; /*boot timestamp in centi-seconds*/ @@ -61,10 +62,79 @@ u_char *time_to_set; /*for setting hrSystemDate*/ struct timeval timeval_to_set; /*for setting hrSystemDate*/ + uint64_t hr_tick; + + struct kvm_swap *swap_devs; /*for kvm_getswapinfo*/ + size_t swap_devs_len; /*idem */ + uint32_t next_hrStorage_index; /*next int availabe for indexing the hrStorageTable*/ + time_t hrStorage_tbl_age; + + + +}; + +/* + * Instance to keep most of the globals related to + * HOST RESOURCES MIB implementation + */ +extern struct hostres_state hrState_g; + +/* + * This structure is used to hold on SNMP table entry + * for HOST-RESOURCES-MIB's hrStorageTable + */ +#define HR_STORAGE_FOUND 0x001 +struct hrStorageTblEntry { + int32_t index; + struct asn_oid type; + u_char descr[255+1]; + int32_t allocationUnits; + int32_t size; + int32_t used; + uint32_t allocationFailures; + uint32_t flags; /*not from the SNMP mib table, only to be used internally*/ + TAILQ_ENTRY(hrStorageTblEntry) link; +}; + + +TAILQ_HEAD(storage_tbl, hrStorageTblEntry); +extern struct storage_tbl storage_tbl; + + +/* + * Next structure is used to keep o list of mappings from a specific + * name (a_name) to an entry in the hrStorageTblEntry; + * We are trying to keep the same index for a specific name at least + * for the duration of one SNMP agent run + */ +struct storageNameMapEntry { + int32_t hrIndex; /*used for hrStorageTblEntry::index*/ + u_char a_name[255+1]; /*map key, also used for hrStorageTblEntry::descr*/ -}hostres_ctx_type; + /*next may be NULL if the respective hrStorageTblEntry is (temporally) gone*/ + struct hrStorageTblEntry *entry_p; + STAILQ_ENTRY(storageNameMapEntry) link; +}; + +STAILQ_HEAD(storage_map_list, storageNameMapEntry); +extern struct storage_map_list storage_name_map; + +/* + * Init the things for hrStorageTable. + */ +void init_hrStorage_tbl_v(void); + +/* + * Finalization routine for hrStorageTable. + * It destroys the lists and frees the heap memory + */ +void fini_hrStorage_tbl_v(void); -extern hostres_ctx_type hostres_ctx_g; +/* + * Refresh routine for hrStorageTable. + * Usable for polling the system for any changes. + */ +void refresh_hrStorage_tbl_v(void); #endif /*__HOSTRES_SNMP_H_INCLUDED__ */