PERFORCE change 80694 for review
soc-victor
soc-victor at FreeBSD.org
Thu Jul 21 19:41:37 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=80694
Change 80694 by soc-victor at 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 at 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]) {
More information about the p4-projects
mailing list