Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Jul 2005 19:41:12 GMT
From:      soc-victor <soc-victor@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 80694 for review
Message-ID:  <200507211941.j6LJfCfO012274@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=80694

Change 80694 by soc-victor@soc-victor_82.76.158.176 on 2005/07/21 19:40:24

	Added SNMP SET support for hrSWRunTable.

Affected files ...

.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile#9 edit
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_scalars.c#7 edit
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_snmp.h#11 edit
.. //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swrun_tbl.c#2 edit

Differences ...

==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/Makefile#9 (text+ko) ====

@@ -1,5 +1,6 @@
 # 
 # Copyright (c) 2005 The FreeBSD Project 
+# All rights reserved.
 # Author: Victor Cruceru <soc-victor@freebsd.org>
 #
 

==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_scalars.c#7 (text+ko) ====

@@ -235,7 +235,7 @@
 			}
 			
 		}
-	} else if (curr_op == SNMP_OP_ROLLBACK )	{
+	} else if (curr_op == SNMP_OP_ROLLBACK ) {
 		switch (value->var.subs[sub - 1]) { 
 			case LEAF_hrSystemDate: {
 				HR_DPRINTF((stderr, "SNMP_OP_ROLLBACK for LEAF_hrSystemDate\n"));
@@ -308,7 +308,7 @@
 		case SNMP_OP_ROLLBACK:
 		case SNMP_OP_COMMIT:
 		case SNMP_OP_GETNEXT:
-	  	default:{
+	  	default: {
 			assert(0);
                 	return  (SNMP_ERR_GENERR);
 		}	
@@ -576,24 +576,30 @@
 		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);
+		}	
+	}	
 
-        if(curr_op == SNMP_OP_GET) {
-		switch (value->var.subs[sub - 1]) {
-			case LEAF_hrSWOSIndex:
-				value->v.uint32 = hrState_g.hrSWOSIndex;
-				return (SNMP_ERR_NOERROR);
-			default:
-				assert(0);
-				return  (SNMP_ERR_NOSUCHNAME);
-			
-		}/*end switch*/	
-	} else if (curr_op == SNMP_OP_SET) {
-		return (SNMP_ERR_NOT_WRITEABLE);
-	} else {
-		assert(0);
-		return  (SNMP_ERR_GENERR);
-	}
+	switch (value->var.subs[sub - 1]) {
+		case LEAF_hrSWOSIndex:
+			value->v.uint32 = hrState_g.hrSWOSIndex;
+			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.h#11 (text+ko) ====

@@ -185,7 +185,8 @@
 	int32_t		perfCPU;
 	int32_t		perfMemory;	
 #define HR_SWRUN_FOUND 0x001
-	uint32_t	flags;			/*not from the SNMP mib table, only to be used internally*/	
+	uint32_t	flags;			/*not from the SNMP mib table, only to be used internally*/
+	uint64_t	r_tick;			/*agent tick when this entry was last time refreshed*/
 	TAILQ_ENTRY(hrSWRunTblEntry) link;		
 };
 

==== //depot/projects/soc2005/bsnmp/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swrun_tbl.c#2 (text+ko) ====

@@ -41,6 +41,8 @@
 #include <sys/sysctl.h>
 #include <sys/user.h>
 #include <sys/linker.h>
+#include <sys/types.h>
+#include <signal.h>
 
 
 #define	IS_KERNPROC(kp)	( ((kp)->ki_flag & P_KTHREAD) == P_KTHREAD )
@@ -150,7 +152,7 @@
 
 static
 void 
-kinfo_proc_to_hrSWRunTblEntry(const struct kinfo_proc *kp, struct hrSWRunTblEntry* entry) {
+kinfo_proc_to_hrSWRunTblEntry_v(const struct kinfo_proc *kp, struct hrSWRunTblEntry* entry) {
 	char **argv = NULL;
 	uint64_t cpu_time = 0;
 	
@@ -162,6 +164,9 @@
 	
 	entry->path[0] = '\0';
 	entry->parameters[0] = '\0';
+	
+	assert(hrState_g.kd != NULL);
+	
 	argv = kvm_getargv(hrState_g.kd, kp, sizeof(entry->parameters) - 1);
 	if(argv !=  NULL){
 		memset(&entry->parameters[0], '\0', sizeof(entry->parameters));
@@ -201,12 +206,13 @@
 	entry->perfCPU = (cpu_time > (uint64_t)INT_MAX ? INT_MAX : cpu_time); 
 	
 	entry->perfMemory = kp->ki_size / 1024; /*in kilo-bytes*/
+	entry->r_tick = get_ticks();
 
 }
 
 static 
 void 
-kld_file_stat_to_hrSWRunTblEntry(const struct kld_file_stat* kfs, struct hrSWRunTblEntry* entry) {
+kld_file_stat_to_hrSWRunTblEntry_v(const struct kld_file_stat* kfs, struct hrSWRunTblEntry* entry) {
 	assert(kfs != NULL);
 	assert(entry != NULL);
 	
@@ -230,6 +236,7 @@
 	entry->status = SRS_RUNNING;
 	entry->perfCPU = 0; /*Info not available*/
 	entry->perfMemory = kfs->size / 1024; /*in kilo-bytes*/
+	entry->r_tick = get_ticks();
 }
 
 /*
@@ -262,7 +269,7 @@
 		assert(entry !=  NULL);
 		entry->flags |= HR_SWRUN_FOUND; /*mark it as found*/
 		
-		kinfo_proc_to_hrSWRunTblEntry(kp,entry);		
+		kinfo_proc_to_hrSWRunTblEntry_v(kp,entry);		
 		
 	}
 }
@@ -295,7 +302,7 @@
 		assert(entry !=  NULL);
 		entry->flags |= HR_SWRUN_FOUND; /*mark it as found*/
 		
-		kld_file_stat_to_hrSWRunTblEntry(&stat, entry);
+		kld_file_stat_to_hrSWRunTblEntry_v(&stat, entry);
 	}    
 	
 }
@@ -332,7 +339,140 @@
 	HR_DPRINTF((stderr, "%s: refresh DONE\n ",__func__));
 }
 
+static
+void fetch_hrSWRun_entry_v(struct hrSWRunTblEntry *entry) {
+	int item_found = 0;
+	struct kinfo_proc *plist =  NULL;
+	int nproc =  -1;
+	int fileid = 0;
+	
+	assert(entry !=  NULL);
+	
+	if( entry->index >= NO_PID + 1)	{
+		/* this is a kernel item */
+		item_found = 0;
+		for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) {
+			struct kld_file_stat stat;
+			stat.version = sizeof(struct kld_file_stat);
+			if (kldstat(fileid, &stat) < 0) {
+				syslog(LOG_ERR, "kldstat() failed: %m");
+				continue;
+			}
+			/*
+			* kernel and kernel files (*.ko) will be indexed starting with
+			* NO_PID + 1; NO_PID is PID_MAX + 1 thus it will be no risk to
+			* overlap with real PIDs which are in range of 1 .. NO_PID
+			*/
+			if( NO_PID + 1 + stat.id == entry->index ) {
+				kld_file_stat_to_hrSWRunTblEntry_v(&stat, entry);
+				item_found = 1;
+				break;
+			}
 
+		} /* end for*/   
+		if (item_found == 0) {
+			/* not found, it's gone. Mark it as invalid for now, it
+			 * will be removed from the list at next global refersh
+			 */  
+			 HR_DPRINTF((stderr, "%s: missing item with kid = %d \n ", __func__, entry->index -  NO_PID - 1));
+			 entry->status = SRS_INVALID;
+			 
+		}
+		
+	} else {
+	
+		/* this is user space visible process*/
+		assert(hrState_g.kd != NULL);
+		plist = kvm_getprocs(hrState_g.kd, KERN_PROC_PID, entry->index - 1, &nproc);
+		if (plist == NULL || nproc != 1) {
+			HR_DPRINTF((stderr, "%s: missing item with PID = %d \n ", __func__, entry->index - 1));
+			entry->status = SRS_INVALID;
+			return; 
+		}
+		kinfo_proc_to_hrSWRunTblEntry_v(plist,entry);
+
+	}
+}
+
+static
+int invalidate_hrSWRun_entry(struct hrSWRunTblEntry *entry) {
+	struct kinfo_proc *plist =  NULL;
+	int nproc =  -1;
+
+	
+	assert(entry !=  NULL);
+	
+	if( entry->index >= NO_PID + 1)	{
+		/* this is a kernel item */
+		int item_found = 0;
+		int fileid = 0;
+
+		HR_DPRINTF((stderr, "%s: atempt to delete a kernel item %d \n ", __func__, entry->index -  NO_PID - 1));
+		
+		if( entry->index == hrState_g.hrSWOSIndex) {
+			/*can't invalidate the kernel itself*/
+			return (SNMP_ERR_NOT_WRITEABLE);/*error*/
+		}
+		
+		for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) {
+			struct kld_file_stat stat;
+			stat.version = sizeof(struct kld_file_stat);
+			if (kldstat(fileid, &stat) < 0) {
+				syslog(LOG_ERR, "kldstat() failed: %m");
+				continue;
+			}
+			
+			if( NO_PID + 1 + stat.id == entry->index ) {
+				if(kldunload(fileid) < 0) {
+					syslog(LOG_ERR,"kldunload for %s failed: %m", stat.name);
+					return (SNMP_ERR_RES_UNAVAIL); /*error*/
+				}
+				item_found = 1;
+				break;
+			}
+
+		} /* end for*/   
+		if (item_found == 0) {
+			/* not found, it's gone. Mark it as invalid for now, it
+			 * will be removed from the list at next global refersh
+			 */  
+			 HR_DPRINTF((stderr, "%s: missing item with kid = %d \n ", __func__, entry->index -  NO_PID - 1));
+			 entry->status = SRS_INVALID;
+			 return (SNMP_ERR_NOERROR); 
+			 
+		}
+		
+	} else {
+	
+		/* this is user space visible process*/
+		assert(hrState_g.kd != NULL);
+		plist = kvm_getprocs(hrState_g.kd, KERN_PROC_PID, entry->index - 1, &nproc);
+		if (plist == NULL || nproc != 1) {
+			HR_DPRINTF((stderr, "%s: missing item with PID = %d \n ", __func__, entry->index - 1));
+			entry->status = SRS_INVALID;
+			return (SNMP_ERR_NOERROR); 
+		}
+		if(IS_KERNPROC(plist)) {
+			/*you don't want to do this*/
+			return (SNMP_ERR_NOT_WRITEABLE);
+		} else {
+			if(kill(entry->index - 1, SIGKILL) < 0) {
+				syslog(LOG_ERR,"kill (%d, SIGKILL) failed: %m", entry->index - 1);
+				return (SNMP_ERR_GENERR);
+			}
+			return (SNMP_ERR_NOERROR); 
+		}
+		
+
+	}
+	return (SNMP_ERR_NOERROR); 
+	
+}
+
+/*
+ * This is the implmenetaion for a generated function prototype, see hostres_tree.h 
+ * It hanldes the SNMP operations for hrSWRunTable
+ */
 int op_hrSWRunTable(struct snmp_context *ctx __unused, 
                 struct snmp_value *value, 
 		u_int sub, 
@@ -374,14 +514,43 @@
 		break;
 
 	  case SNMP_OP_SET:
-		return (SNMP_ERR_NOT_WRITEABLE);	  
+		if (value->var.len - sub != 1) {
+			return (SNMP_ERR_NOSUCHNAME);
+		}
+			
+		if ((entry = hrSWRunTblEntry_find_by_index(value->var.subs[sub])) == NULL) {
+			return (SNMP_ERR_NOSUCHNAME);
+		}
+		
+		if (entry->r_tick < this_tick) {
+			HR_DPRINTF((stderr, "%s: Specific entry with SNMP INDEX = %d needs refresh\n ",
+					__func__, 
+					entry->index));
+			fetch_hrSWRun_entry_v(entry);
+		}	
+		if(entry->status == SRS_INVALID){
+			return (SNMP_ERR_NOERROR);
+		}
+		
+		switch (value->var.subs[sub - 1]) {
+			case LEAF_hrSWRunStatus: {
+				if( value->v.integer !=  SRS_INVALID) {
+					return (SNMP_ERR_WRONG_VALUE);
+				}
+				return (invalidate_hrSWRun_entry(entry));
+			}	
+			default:
+				return (SNMP_ERR_NOT_WRITEABLE);
+
+		} /* end switch (value->var.subs[sub - 1]) */
+		return (SNMP_ERR_NOERROR);
 
 	  case SNMP_OP_ROLLBACK:
 	  case SNMP_OP_COMMIT:
-	  	assert(0);
 		return (SNMP_ERR_NOERROR);
 	}
 
+
 	ret = SNMP_ERR_NOERROR;
 	switch (value->var.subs[sub - 1]) {
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200507211941.j6LJfCfO012274>