Date: Sun, 14 Aug 2005 18:29:41 GMT From: Victor Cruceru <soc-victor@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 81988 for review Message-ID: <200508141829.j7EITf9T073121@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=81988 Change 81988 by soc-victor@soc-victor_82.76.158.176 on 2005/08/14 18:28:58 Finished the SNMP instrumentation for hrSWInstalledTable. Also implemented the two scalars associated with this table: hrSWInstalledLastChange and hrSWInstalledLastUpdateTime. Affected files ... .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile#20 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_scalars.c#10 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c#19 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.h#23 edit .. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swinstalled_tbl.c#2 edit Differences ... ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile#20 (text+ko) ==== ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_scalars.c#10 (text+ko) ==== @@ -603,3 +603,66 @@ } + +int op_hrSWInstalled(struct snmp_context *ctx __unused, + struct snmp_value *value __unused, + u_int sub, + u_int iidx __unused, + enum snmp_op curr_op ) +{ + /*only SNMP GET is possible*/ + switch (curr_op) { + case SNMP_OP_GET: + break; + case SNMP_OP_SET: + return (SNMP_ERR_NOT_WRITEABLE); + case SNMP_OP_ROLLBACK: + case SNMP_OP_COMMIT: + case SNMP_OP_GETNEXT: + default: { + assert(0); + return (SNMP_ERR_GENERR); + } + } + + switch (value->var.subs[sub - 1]) { + case LEAF_hrSWInstalledLastChange:{ + + if (hrState_g.hr_sw_installed_change_tick <= start_tick) { + value->v.uint32 = 0; + } else { + uint64_t lastChange = + hrState_g.hr_sw_installed_change_tick - start_tick; + + value->v.uint32 = ( lastChange > (uint64_t)UINT_MAX ? + UINT_MAX : + lastChange ); /*may overflow the SNMP type*/ + + } + + return (SNMP_ERR_NOERROR); + } + case LEAF_hrSWInstalledLastUpdateTime: { + if (hrState_g.hr_sw_installed_full_upd_tick <= start_tick) { + value->v.uint32 = 0; + } else { + uint64_t lastUpd = + hrState_g.hr_sw_installed_full_upd_tick - start_tick; + + value->v.uint32 = ( lastUpd > (uint64_t)UINT_MAX ? + UINT_MAX : + lastUpd ); /*may overflow the SNMP type*/ + + } + + return (SNMP_ERR_NOERROR); + } + default: + assert(0); + return (SNMP_ERR_NOSUCHNAME); + + }/*end switch*/ + +} + + ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.c#19 (text+ko) ==== @@ -214,6 +214,8 @@ hrState_g.hr_sw_installed_tick = 0; hrState_g.hr_sw_installed_change_tick = 0; hrState_g.hrSWInstalled_tbl_age = 0; + hrState_g.os_pkg_last_change = 0; + hrState_g.hr_sw_installed_full_upd_tick = 0; hrState_g.hr_storage_tick = 0; hrState_g.hr_fs_tick = 0; @@ -347,7 +349,7 @@ hrState_g.hr_sw_installed_tick = 0; hrState_g.hr_sw_installed_change_tick = 0; hrState_g.hrSWInstalled_tbl_age = 0; - + hrState_g.os_pkg_last_change = 0; if (hrState_g.ata_fd > 0) { if (close(hrState_g.ata_fd) < 0) { @@ -365,6 +367,10 @@ if( host_registration_id > 0){ or_unregister(host_registration_id); } + + /*paranoia*/ + memset(&hrState_g, 0, sizeof(hrState_g)); + HR_DPRINTF((stderr, "[%s] done.\n", __func__)); return (0); } @@ -500,14 +506,6 @@ -int op_hrSWInstalled(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); -} ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.h#23 (text+ko) ==== @@ -385,6 +385,7 @@ int32_t type; /* one item from enum SWInstalledType, see above */ u_char date[11]; #define HR_SWINSTALLED_FOUND 0x001 +#define HR_SWINSTALLED_IMMUTABLE 0x002 /*next items are not from the SNMP mib table, only to be used internally*/ uint32_t flags; TAILQ_ENTRY(hrSWInstalledTblEntry) link; @@ -532,10 +533,12 @@ struct sw_installed_tbl hr_sw_installed_tbl; /*the head of the list with hrSWInstalledTable's entries */ uint32_t next_hrSWInstalled_index; /*next int available for indexing the hrSWInstalledTable*/ - uint64_t hr_sw_installed_tick; /*last (agent) tick when hrSWInstalledTable was fully updated */ + uint64_t hr_sw_installed_tick; /*last (agent) tick when hrSWInstalledTable was updated */ uint64_t hr_sw_installed_change_tick; /*last (agent) tick when hrDeviceTable was last changed */ + uint64_t hr_sw_installed_full_upd_tick; /*last (agent) tick when hrDeviceTable was fully updated */ time_t hrSWInstalled_tbl_age; + time_t os_pkg_last_change; }; ==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swinstalled_tbl.c#2 (text+ko) ==== @@ -41,6 +41,8 @@ #include <err.h> #include <sys/utsname.h> #include <sys/stat.h> +#include <sys/syslimits.h> +#include <dirent.h> extern u_char* OS_getSystemInitialLoadParameters(void); @@ -158,6 +160,9 @@ } +/* + * Get the *running* O/S identification + */ static void hrSWInstalled_get_OS_ident(void) { struct utsname os_id; @@ -169,8 +174,9 @@ if (uname(&os_id) != 0) { return; } - snprintf(os_string, sizeof(os_string) - 1, "%s %s %s", - os_id.sysname, os_id.release, os_id.version); + + snprintf(os_string, sizeof(os_string) - 1, "%s: %s", + os_id.sysname, os_id.version); entry = hrSWInstalledTblEntry_find_by_name(os_string); if (entry == NULL) { @@ -181,7 +187,7 @@ memset(&sb, 0, sizeof(sb)); - entry->flags |= HR_SWINSTALLED_FOUND; + entry->flags |= (HR_SWINSTALLED_FOUND | HR_SWINSTALLED_IMMUTABLE); entry->id = oid_zeroDotZero; entry->type= SWI_OPERATING_SYSTEM; memset(&entry->date[0], 0, sizeof(entry->date)); @@ -216,7 +222,151 @@ } } +static +void hrSWInstalled_get_packages(void) { +/* Where we put logging information by default, else ${PKG_DBDIR} if set */ +#define DEF_LOG_DIR "/var/db/pkg" +/* just in case we change the environment variable name */ +#define PKG_DBDIR "PKG_DBDIR" +/* macro to get name of directory where we put logging information */ +#define LOG_DIR (getenv(PKG_DBDIR) ? getenv(PKG_DBDIR) : DEF_LOG_DIR) +#define CONTENTS_FNAME "+CONTENTS" + char pkg_dir[PATH_MAX]; /*1024, for sure it's too much for this situation*/ + struct stat sb; + DIR *p_dir = NULL; + struct dirent dir_entry; + struct dirent *result = NULL; + int return_code = -1; + struct hrSWInstalledTblEntry *entry = NULL; + + memset(&pkg_dir[0], 0, sizeof(pkg_dir)); + memset(&sb, 0, sizeof(sb)); + + snprintf(pkg_dir, sizeof(pkg_dir) - 1, "%s", LOG_DIR); + if (stat(pkg_dir, &sb) != 0) { + syslog(LOG_ERR, "hrSWInstalledTable: stat(\"%s\") failed: %m ", pkg_dir); + return; + } + if (!S_ISDIR(sb.st_mode)) { + syslog(LOG_ERR, "hrSWInstalledTable: \"%s\" is not a directory! ", pkg_dir); + return; + } + if (sb.st_ctime <= hrState_g.os_pkg_last_change) { + HR_DPRINTF((stderr, "%s: no need to rescan installed packages, directory time-stamp unmodified \n ", + __func__)); + TAILQ_FOREACH(entry, &hrState_g.hr_sw_installed_tbl, link) + entry->flags |= HR_SWINSTALLED_FOUND; + return; + } + + + + p_dir = opendir(pkg_dir); + if (p_dir == NULL) { + syslog(LOG_ERR, "hrSWInstalledTable: opendir(\"%s\") failed: %m ", pkg_dir); + return; + } + + for (return_code = readdir_r(p_dir, &dir_entry, &result); + result != NULL && return_code == 0; + return_code = readdir_r(p_dir, &dir_entry, &result) ) { + + struct tm k_ts; + char pkg_file[PATH_MAX] = ""; + + + + HR_DPRINTF((stderr,">>pkg file: %s\n", dir_entry.d_name)); + if (strncmp(dir_entry.d_name, ".", 1) == 0 || + strncmp(dir_entry.d_name, "..", 2) == 0 || + strncmp(dir_entry.d_name,"pkgdb.db", 8) == 0 ) { + continue; + } + + + + snprintf(pkg_file, sizeof(pkg_file) - 1, "%s/%s/%s", + pkg_dir, + dir_entry.d_name, + CONTENTS_FNAME); + + + if (stat(pkg_file, &sb) != 0 ) { + continue; + } + if (!S_ISREG(sb.st_mode)) { + syslog(LOG_ERR, "hrSWInstalledTable: \"%s\" not a regular file, pkg. skipped ", pkg_file); + continue; + } + + entry = hrSWInstalledTblEntry_find_by_name(dir_entry.d_name); + if (entry == NULL) { + + if ((entry = hrSWInstalledTblEntry_create(dir_entry.d_name)) == NULL) { + goto PKG_LOOP_END; + } + + /*new entry, update the timestamp*/ + hrState_g.hr_sw_installed_change_tick = get_ticks(); + } + + memset(&sb, 0, sizeof(sb)); + memset(&pkg_file[0], 0, sizeof(pkg_file)); + + + entry->flags |= HR_SWINSTALLED_FOUND; + entry->id = oid_zeroDotZero; + entry->type= SWI_APPLICATION; + memset(&entry->date[0], 0, sizeof(entry->date)); + + snprintf(pkg_file, sizeof(pkg_file) - 1, "%s/%s", pkg_dir, dir_entry.d_name); + + + if(stat(pkg_file, &sb) == 0) { + if(localtime_r(&sb.st_ctime, &k_ts) != NULL) { + entry->date[0] = (u_char)((k_ts.tm_year + 1900) >> 8); + entry->date[1] = (u_char)(k_ts.tm_year + 1900); + entry->date[2] = k_ts.tm_mon + 1; + entry->date[3] = k_ts.tm_mday; + entry->date[4] = k_ts.tm_hour; + entry->date[5] = k_ts.tm_min; + entry->date[6] = k_ts.tm_sec; + entry->date[7] = 0; /*deci-seconds */ + + if (k_ts.tm_gmtoff < 0){ + entry->date[8] = '-'; + }else{ + entry->date[8] = '+'; + } + entry->date[9] = (u_char)(abs(k_ts.tm_gmtoff) / 3600); + entry->date[10] = (u_char)((abs(k_ts.tm_gmtoff) - entry->date[9] * 3600) / 60); + + } + } + + + + + + }/*end for*/ + + if (return_code != 0) { + syslog(LOG_ERR, "hrSWInstalledTable: readdir_r(\"%s\") failed: %m ", pkg_dir); + } else { + /*save the timestamp of directory + to avoid any further scanning*/ + hrState_g.os_pkg_last_change = sb.st_ctime; + } + +PKG_LOOP_END: + if ( p_dir != NULL ) { + closedir(p_dir); + } + + +} + void init_hrSWInstalled_tbl_v(void) { hrSWInstalled_get_OS_ident(); refresh_hrSWInstalled_tbl_v(); @@ -228,7 +378,7 @@ void refresh_hrSWInstalled_tbl_v(void) { struct hrSWInstalledTblEntry *entry = NULL, *entry_tmp; - if ( this_tick <= hrState_g.hr_fs_tick) { + if ( this_tick <= hrState_g.hr_sw_installed_tick) { HR_DPRINTF((stderr, "%s: no refresh needed\n ",__func__)); return; } @@ -239,13 +389,17 @@ entry->flags &= ~HR_SWINSTALLED_FOUND; - /*------------------------------------*/ + hrSWInstalled_get_packages(); entry = TAILQ_FIRST(&hrState_g.hr_sw_installed_tbl); while (entry != NULL) { entry_tmp = TAILQ_NEXT(entry, link); - if (!(entry->flags & HR_SWINSTALLED_FOUND)) + if (!(entry->flags & HR_SWINSTALLED_FOUND) && !(entry->flags & HR_SWINSTALLED_IMMUTABLE) ) { hrSWInstalledTblEntry_delete_v(entry); + /*entry deleted, update the timestamp*/ + hrState_g.hr_sw_installed_change_tick = get_ticks(); + + } entry = entry_tmp; } @@ -253,6 +407,7 @@ hrState_g.hrSWInstalled_tbl_age = time(NULL); + hrState_g.hr_sw_installed_full_upd_tick = get_ticks(); HR_DPRINTF((stderr, "%s: refresh DONE\n ",__func__)); @@ -267,7 +422,11 @@ { struct hrSWInstalledTblEntry *entry = NULL; int ret = SNMP_ERR_NOERROR; - + + if ( (time(NULL) - hrState_g.hrSWInstalled_tbl_age) > HR_SWINSTALLED_TBL_REFRESH ) { + HR_DPRINTF((stderr, "%s: need refresh\n ", __func__)); + refresh_hrSWInstalled_tbl_v(); + } switch (curr_op) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508141829.j7EITf9T073121>