From owner-p4-projects@FreeBSD.ORG Thu Jul 21 19:41:36 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 6CF7616A421; Thu, 21 Jul 2005 19:41:36 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2554316A41F for ; Thu, 21 Jul 2005 19:41:36 +0000 (GMT) (envelope-from soc-victor@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9263243D53 for ; Thu, 21 Jul 2005 19:41:12 +0000 (GMT) (envelope-from soc-victor@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j6LJfCQJ012277 for ; Thu, 21 Jul 2005 19:41:12 GMT (envelope-from soc-victor@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j6LJfCfO012274 for perforce@freebsd.org; Thu, 21 Jul 2005 19:41:12 GMT (envelope-from soc-victor@freebsd.org) Date: Thu, 21 Jul 2005 19:41:12 GMT Message-Id: <200507211941.j6LJfCfO012274@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to soc-victor@freebsd.org using -f From: soc-victor To: Perforce Change Reviews Cc: Subject: PERFORCE change 80694 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 21 Jul 2005 19:41:37 -0000 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 # ==== //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 #include #include +#include +#include #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]) {