On Fri, Feb 7, 2014 at 5:46 AM, Zdenek Styblik <zdenek.styb...@gmail.com> wrote:
> Hello,
>
> here is my proposal to re-design and re-work of ipmitool's PEF user
> interface. This is as a reaction to Jordan Hargrave's request to add
> 'pef setpolicy'.
> This is all based on chapter 30. PEF and Alerting Commands, IPMIv2.0
> p.375. Aim isn't to implement all these commands, but to outline user
> interface, so these commands can be implemented eventually.
> There are couple unresolved commands and feel free to chip in your
> ideas how to solve them. :)
>
> Let's set deadline for comments until 28th February 2014.
>
> <Chapter> <Title>
> 30.0 Help
>  * 'pef help'
>
> 30.1 Get PEF Capabilities
>  * 'pef info' - it's ok, but should be accompanied/complemented with
> 'pef capabilities' or something
>
> 30.2 Arm PEF Postpone Timer
>  * 'pef timer get' - this implies user input equal to 0xFFh
>  * 'pef timer set <0x00-0xFFh>'
>
> 30.3 Set PEF Config Parameters
> 30.4 Get PEF Config Parameters
>  * 'pef policy list'
>  * 'pef policy enable <policy_id>'
>  * 'pef policy disable <policy_id>'
>  * 'pef policy create <policy_id> <params>'
>  * 'pef policy delete <policy_id>'
>  * and the same thing for 'pef filters'
>
> 30.6 Set Last Processed Event ID
> * unresolved despite it pretty much is '<something> <SEL_id>', but to
> figure out name of <something> :)
>
> 30.7 Get Last Processed Event ID
>  * 'pef status' -> I have no idea, but 'status' is misleading/wrong
> given the context, although Oracle's documentation puts it in a way it
> makes sense, quote: ``Print the current PEF status (the last SEL entry
> processed by the BMC, etc).''
>
> 30.8 PET Acknowledge
>  * 'pef pet ack <params>'
>
> 30.7 Alert Immediate
>  * unresolved - I haven't figured out this one
>
> Changes to current/standing commands:
>  * 'pef list' - it lists all entries in PEF
>  * 'pef policy' - replaced with 'pef policy list'
>
> Best regards,
> Z.
>

Attached is a patch for proposition above. This should make way for
``Add support for enable/disable PEF policy entries'' -
https://sourceforge.net/p/ipmitool/bugs/323/
Comments and code reviews are welcome. After all, that's the way forward.

Regards,
Z.

> --
> Zdenek Styblik
> email: zdenek.styb...@gmail.com
> jabber: zdenek.styb...@gmail.com
diff --git a/lib/ipmi_pef.c b/lib/ipmi_pef.c
index 154bf40..b6d6687 100644
--- a/lib/ipmi_pef.c
+++ b/lib/ipmi_pef.c
@@ -75,6 +75,8 @@ static const char * pef_flag_fmts[][3] = {
 };
 static const char * listitem[] =	{" | %s", ",%s", "%s"};
 
+void ipmi_pef_policy_help(void);
+
 const char * 
 ipmi_pef_bit_desc(struct bit_desc_map * map, uint32_t value)
 {	/*
@@ -226,14 +228,18 @@ ipmi_pef_get_policy_table(struct ipmi_intf * intf,
 	req.msg.data = (uint8_t *)&psel;
 	req.msg.data_len = sizeof(psel);
 	rsp = ipmi_pef_msg_exchange(intf, &req, "Alert policy table size");
-	if (!rsp)
+	if (!rsp) {
 		return(0);
+	}
 	tbl_size = (rsp->data[1] & PEF_POLICY_TABLE_SIZE_MASK);
 	i = (tbl_size * sizeof(struct pef_cfgparm_policy_table_entry));
-	if (!i
-	|| (ptbl = (struct pef_cfgparm_policy_table_entry *)malloc(i)) == NULL)
+	if (!i) {
+		return 0;
+	}
+	ptbl = (struct pef_cfgparm_policy_table_entry *)malloc(i);
+	if (ptbl == NULL) {
 		return(0);
-
+	}
 	memset(&psel, 0, sizeof(psel));
 	psel.id = PEF_CFGPARM_ID_PEF_ALERT_POLICY_TABLE_ENTRY;
 	for (ptmp=ptbl, i=1; i<=tbl_size; i++) {
@@ -660,25 +666,27 @@ ipmi_pef_list_entries(struct ipmi_intf * intf)
 	}
 }
 
-static void
+/* ipmi_pef_list_policies - list PEF alert policies
+ */
+int
 ipmi_pef_list_policies(struct ipmi_intf * intf)
-{	/*
-	// list PEF alert policies
-	*/
+{
 	struct ipmi_rs * rsp;
 	struct ipmi_rq req;
 	struct pef_cfgparm_policy_table_entry * ptbl = NULL;
 	struct pef_cfgparm_policy_table_entry * ptmp = NULL;
-	uint32_t i;
+	int rc = 0;
 	uint8_t wrk, ch, medium, tbl_size;
+	uint32_t i;
 
 	tbl_size = ipmi_pef_get_policy_table(intf, &ptbl);
-	if (!tbl_size) {
+	if (tbl_size == 0) {
 		if (!ptbl) {
 			free(ptbl);
 			ptbl = NULL;
 		}
-		return;
+		lprintf(LOG_ERR, "Failed to get PEF policy table.");
+		return (-1);
 	}
 	memset(&req, 0, sizeof(req));
 	req.msg.netfn = IPMI_NETFN_APP;
@@ -686,53 +694,57 @@ ipmi_pef_list_policies(struct ipmi_intf * intf)
 	req.msg.data = &ch;
 	req.msg.data_len = sizeof(ch);
 	for (ptmp=ptbl, i=1; i<=tbl_size; i++, ptmp++) {
-		if ((ptmp->entry.policy & PEF_POLICY_ENABLED) == PEF_POLICY_ENABLED) {
-			if (i > 1)
-				printf("\n");
-			first_field = 1;
-			ipmi_pef_print_dec("Alert policy table entry",
-						(ptmp->data1 & PEF_POLICY_TABLE_ID_MASK));
-			ipmi_pef_print_dec("Policy set",
-						(ptmp->entry.policy & PEF_POLICY_ID_MASK) >> PEF_POLICY_ID_SHIFT);
-			ipmi_pef_print_str("Policy entry rule",
-						ipmi_pef_bit_desc(&pef_b2s_policies, (ptmp->entry.policy & PEF_POLICY_FLAGS_MASK)));
-
-			if (ptmp->entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) {
-				ipmi_pef_print_str("Event-specific", "true");
-//				continue;
-			}			
-			wrk = ptmp->entry.chan_dest;
-
-			/* channel/description */
-			ch = (wrk & PEF_POLICY_CHANNEL_MASK) >> PEF_POLICY_CHANNEL_SHIFT;
-			rsp = ipmi_pef_msg_exchange(intf, &req, "Channel info");
-			if (!rsp || rsp->data[0] != ch) {
-				lprintf(LOG_ERR, " **Error retrieving %s",
-					"Channel info");
-				continue;
-			}
-			medium = rsp->data[1];
-			ipmi_pef_print_dec("Channel number", ch);
-			ipmi_pef_print_str("Channel medium",
-						ipmi_pef_bit_desc(&pef_b2s_ch_medium, medium));
-
-			/* destination/description */
-			wrk &= PEF_POLICY_DESTINATION_MASK;
-			switch (medium) {
-				case PEF_CH_MEDIUM_TYPE_LAN:
-					ipmi_pef_print_lan_dest(intf, ch, wrk);
-					break;
-				case PEF_CH_MEDIUM_TYPE_SERIAL:
-					ipmi_pef_print_serial_dest(intf, ch, wrk);
-					break;
-				default:
-					ipmi_pef_print_dest(intf, ch, wrk);
-					break;
-			}
+		if ((ptmp->entry.policy & PEF_POLICY_ENABLED) != PEF_POLICY_ENABLED) {
+			/* Why do we list only enabled policies?! */
+			continue;
+		}
+		if (i > 1) {
+			printf("\n");
+		}
+		first_field = 1;
+		ipmi_pef_print_dec("Alert policy table entry",
+					(ptmp->data1 & PEF_POLICY_TABLE_ID_MASK));
+		ipmi_pef_print_dec("Policy set",
+					(ptmp->entry.policy & PEF_POLICY_ID_MASK) >> PEF_POLICY_ID_SHIFT);
+		ipmi_pef_print_str("Policy entry rule",
+				ipmi_pef_bit_desc(&pef_b2s_policies,
+					(ptmp->entry.policy & PEF_POLICY_FLAGS_MASK)));
+
+		if (ptmp->entry.alert_string_key & PEF_POLICY_EVENT_SPECIFIC) {
+			ipmi_pef_print_str("Event-specific", "true");
+		}			
+		wrk = ptmp->entry.chan_dest;
+
+		/* channel/description */
+		ch = (wrk & PEF_POLICY_CHANNEL_MASK) >> PEF_POLICY_CHANNEL_SHIFT;
+		rsp = ipmi_pef_msg_exchange(intf, &req, "Channel info");
+		if (!rsp || rsp->data[0] != ch) {
+			lprintf(LOG_ERR, " **Error retrieving %s", "Channel info");
+			rc = (-1);
+			continue;
+		}
+		medium = rsp->data[1];
+		ipmi_pef_print_dec("Channel number", ch);
+		ipmi_pef_print_str("Channel medium",
+					ipmi_pef_bit_desc(&pef_b2s_ch_medium, medium));
+
+		/* destination/description */
+		wrk &= PEF_POLICY_DESTINATION_MASK;
+		switch (medium) {
+			case PEF_CH_MEDIUM_TYPE_LAN:
+				ipmi_pef_print_lan_dest(intf, ch, wrk);
+				break;
+			case PEF_CH_MEDIUM_TYPE_SERIAL:
+				ipmi_pef_print_serial_dest(intf, ch, wrk);
+				break;
+			default:
+				ipmi_pef_print_dest(intf, ch, wrk);
+				break;
 		}
 	}
 	free(ptbl);
 	ptbl = NULL;
+	return rc;
 }
 
 static void
@@ -794,11 +806,15 @@ ipmi_pef_get_status(struct ipmi_intf * intf)
 	ipmi_pef_print_flags(&pef_b2s_actions, P_ACTV, rsp->data[1]);
 }
 
-static void
-ipmi_pef_get_info(struct ipmi_intf * intf)
-{	/*
-	// report PEF capabilities + System GUID
-	*/
+/* ipmi_pef_get_capabilities - get PEF Capabilities of BMC as described in 30.1
+ * Get PEF Capabilities Command in IPMIv2.0 specification
+ *
+ * returns zero on success
+ * returns (-1) on error
+ */
+int
+ipmi_pef_get_capabilities(struct ipmi_intf *intf)
+{
 	struct ipmi_rs * rsp;
 	struct ipmi_rq req;
 	struct pef_capabilities * pcap;
@@ -817,10 +833,18 @@ ipmi_pef_get_info(struct ipmi_intf * intf)
 	req.msg.netfn = IPMI_NETFN_SE;
 	req.msg.cmd = IPMI_CMD_GET_PEF_CAPABILITIES;
 	rsp = ipmi_pef_msg_exchange(intf, &req, "PEF capabilities");
-	if (!rsp)
-		return;
+	if (rsp == NULL) {
+		lprintf(LOG_ERR, "No response received.");
+		return (-1);
+	} else if (rsp->ccode != 0x00) {
+		lprintf(LOG_ERR, "Get PEF Capabilities command failed: %s",
+				val2str(rsp->ccode, completion_code_vals));
+		return (-1);
+	} else if (rsp->data_len != 4) {
+		lprintf(LOG_ERR, "Invalid data received");
+		return (-1);
+	}
 	pcap = (struct pef_capabilities *)rsp->data;
-
 	ipmi_pef_print_1xd("Version", pcap->version);
 	ipmi_pef_print_dec("PEF table size", pcap->tblsize);
 	ipmi_pef_print_dec("Alert policy table size", tbl_size);
@@ -835,56 +859,158 @@ ipmi_pef_get_info(struct ipmi_intf * intf)
 	req.msg.data_len = sizeof(psel);
 	rsp = ipmi_pef_msg_exchange(intf, &req, "System GUID");
 	uid = NULL;
-	if (rsp && (rsp->data[1] & PEF_SYSTEM_GUID_USED_IN_PET))
+	if (rsp != NULL && rsp->data_len > 1
+			&& (rsp->data[1] & PEF_SYSTEM_GUID_USED_IN_PET)) {
 		uid = &rsp->data[2];
-	else {
+	} else {
 		memset(&req, 0, sizeof(req));
 		req.msg.netfn = IPMI_NETFN_APP;
 		req.msg.cmd = IPMI_CMD_GET_SYSTEM_GUID;
 		rsp = ipmi_pef_msg_exchange(intf, &req, "System GUID");
-		if (rsp)
+		if (rsp != NULL && rsp->data_len > 0) {
 			uid = &rsp->data[0];
+		}
 	}
-	if (uid) {		/* got GUID? */
-		if (verbose)
+	/* got GUID? */
+	if (uid != NULL) {
+		if (verbose) {
 			printf(pef_fld_fmts[F_UID][0], KYWD_LENGTH, "System GUID",
 					uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7],
 					uid[8], uid[9], uid[10],uid[11],uid[12],uid[13],uid[14],uid[15]);
-		else
+		} else {
 			printf(pef_fld_fmts[F_UID][1],
 					uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7],
 					uid[8], uid[9], uid[10],uid[11],uid[12],uid[13],uid[14],uid[15]);
+		}
 	}
 	ipmi_pef_print_flags(&pef_b2s_actions, P_SUPP, actions);
+	return 0;
 }
 
-int ipmi_pef_main(struct ipmi_intf * intf, int argc, char ** argv)
-{	/*
-	// PEF subcommand handling
-	*/
-	int help = 0;
-    int rc = 0;
-
-	if (!argc || !strncmp(argv[0], "info", 4))
-		ipmi_pef_get_info(intf);
-	else if (!strncmp(argv[0], "help", 4))
-		help = 1;
-	else if (!strncmp(argv[0], "status", 6))
-		ipmi_pef_get_status(intf);
-	else if (!strncmp(argv[0], "policy", 6))
-		ipmi_pef_list_policies(intf);
-	else if (!strncmp(argv[0], "list", 4))
-		ipmi_pef_list_entries(intf);
-	else {
-		help = 1;
-        rc   = -1;
-		lprintf(LOG_ERR, "Invalid PEF command: '%s'\n", argv[0]);
+int
+ipmi_pef_event(struct ipmi_intf *intf, int argc, char **argv)
+{
+	lprintf(LOG_ERR, "Not implemented");
+	return (-1);
+}
+
+int
+ipmi_pef_filter(struct ipmi_intf *intf, int argc, char **argv)
+{
+	lprintf(LOG_ERR, "Not implemented");
+	return (-1);
+}
+
+/* ipmi_pef_help - print-out help text
+ *
+ * returns void
+ */
+void
+ipmi_pef_help(void)
+{
+	lprintf(LOG_NOTICE,
+"usage: pef <command> [options]");
+	lprintf(LOG_NOTICE,
+"    capabilities    Display PEF capabilities");
+	lprintf(LOG_NOTICE,
+"    info            Equivalent to capabilities");
+	lprintf(LOG_NOTICE,
+"    policy          Manage PEF policies");
+	lprintf(LOG_NOTICE,
+"    status          Display status of PEF processing");
+}
+
+int
+ipmi_pef_pet(struct ipmi_intf *intf, int argc, char **argv)
+{
+	lprintf(LOG_ERR, "Not implemented");
+	return (-1);
+}
+
+int
+ipmi_pef_policy(struct ipmi_intf *intf, int argc, char **argv)
+{
+	int rc = 0;
+	if (argc < 1) {
+		lprintf(LOG_ERR, "Not enough parameters given.");
+		return (-1);
+	}
+	if (!strncmp(argv[0], "help\0", 5)) {
+		ipmi_pef_policy_help();
+		rc = 0;
+	} else if (!strncmp(argv[0], "list\0", 5)) {
+		rc = ipmi_pef_list_policies(intf);
+	} else if (!strncmp(argv[0], "enable\0", 7)) {
+		lprintf(LOG_ERR, "Not implemented");
+		rc = (-1);
+	} else if (!strncmp(argv[0], "disable\0", 8)) {
+		lprintf(LOG_ERR, "Not implemented");
+		rc = (-1);
+	} else if (!strncmp(argv[0], "create\0", 7)) {
+		lprintf(LOG_ERR, "Not implemented");
+		rc = (-1);
+	} else if (!strncmp(argv[0], "delete\0", 7)) {
+		lprintf(LOG_ERR, "Not implemented");
+		rc = (-1);
+	} else {
+		lprintf(LOG_ERR, "Invalid PEF policy command: %s", argv[0]);
+		ipmi_pef_policy_help();
+		rc = (-1);
 	}
+	return rc;
+}
 
-	if (help)
-		lprintf(LOG_NOTICE, "PEF commands: info status policy list");
-	else if (!verbose)
-		printf("\n");
+void
+ipmi_pef_policy_help(void)
+{
+	lprintf(LOG_NOTICE,
+"usage: pef policy <command> [options]");
+	lprintf(LOG_NOTICE,
+"    list    List enabled PEF policies");
+}
+
+int
+ipmi_pef_timer(struct ipmi_intf *intf, int argc, char **argv)
+{
+	lprintf(LOG_ERR, "Not implemented");
+	return (-1);
+}
 
+int
+ipmi_pef_main(struct ipmi_intf *intf, int argc, char **argv)
+{
+	/* TODO - missing:
+	 *  - 30.5 Set Last Processed Event ID
+	 *  - 30.6 Get Last Processed Event ID - actually covered by 'status'
+	 *  - 30.7 Alert Immediate
+	 */
+	int rc = 0;
+	if (argc < 1) {
+		lprintf(LOG_ERR, "Not enough parameters given.");
+		ipmi_pef_help();
+		rc = (-1);
+	}
+	if (!strncmp(argv[0], "help\0", 5)) {
+		ipmi_pef_help();
+		rc = 0;
+	} else if (!strncmp(argv[0], "info\0", 5)
+			|| !strncmp(argv[0], "capabilities\0", 13)) {
+		rc = ipmi_pef_get_capabilities(intf);
+	} else if (!strncmp(argv[0], "event\0", 6)) {
+		rc = ipmi_pef_event(intf, (argc - 1), ++argv);
+	} else if (!strncmp(argv[0], "filter\0", 7)) {
+		rc = ipmi_pef_filter(intf, (argc - 1), ++argv);
+	} else if (!strncmp(argv[0], "policy\0", 7)) {
+		rc = ipmi_pef_policy(intf, (argc - 1), ++argv);
+	} else if (!strncmp(argv[0], "pet\0", 4)) {
+		rc = ipmi_pef_pet(intf, (argc - 1), ++argv);
+	} else if (!strncmp(argv[0], "status\0", 7)) {
+		ipmi_pef_get_status(intf);
+	} else if (!strncmp(argv[0], "timer\0", 6)) {
+		rc = ipmi_pef_timer(intf, (argc - 1), ++argv);
+	} else {
+		lprintf(LOG_ERR, "Invalid PEF command: %s", argv[0]);
+		rc = (-1);
+	}
 	return rc;
 }
------------------------------------------------------------------------------
"Accelerate Dev Cycles with Automated Cross-Browser Testing - For FREE
Instantly run your Selenium tests across 300+ browser/OS combos.
Get unparalleled scalability from the best Selenium testing platform available
Simple to use. Nothing to install. Get started now for free."
http://p.sf.net/sfu/SauceLabs
_______________________________________________
Ipmitool-devel mailing list
Ipmitool-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ipmitool-devel

Reply via email to