PERFORCE change 81988 for review
Victor Cruceru
soc-victor at FreeBSD.org
Sun Aug 14 18:29:43 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=81988
Change 81988 by soc-victor at 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) {
More information about the p4-projects
mailing list