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