[PATCH] Introduce IPMI BMC Info

Jeremy Kerr jk at ozlabs.org
Tue May 3 07:58:19 UTC 2016


Hi Deb,

> This feature adds the foundation to perform an IPMI BMC Info
> check that will determine if a Host is capable of
> IPMI messaging and if so will perform a basic IPMI message
> exchange to determine the version of IPMI running
> on the hardware.  In the future the IPMI infrastructure
> can be used to further interrogate the FRU Inventory and other
> Sensors to help correlate data and surface any
> discrepancies on inventory or hardware characteristics.

Nice! A few comments:

> +#include <unistd.h>
> +
> +#include "fwts.h"
> +
> +int fwts_bmc_info_check(
> +	fwts_framework *fw)
> +{
> +	fwts_ipmi_rsp *fwts_bmc_info;
> +	fwts_bmc_info = calloc(1, sizeof(fwts_ipmi_rsp));

Do we need to calloc() that? Can we just use it directly from the stack
instead?

> diff --git a/src/lib/src/fwts_firmware.c b/src/lib/src/fwts_firmware.c
> index 5092ac9..6001cd5 100644
> --- a/src/lib/src/fwts_firmware.c
> +++ b/src/lib/src/fwts_firmware.c
> @@ -32,6 +32,7 @@ static struct {
>  } feature_names[] = {
>  	{ FWTS_FW_FEATURE_ACPI,		"ACPI" },
>  	{ FWTS_FW_FEATURE_DEVICETREE,	"devicetree" },
> +	{ FWTS_FW_FEATURE_IPMI,		"IPMI" },
>  };
>  
>  /*
> @@ -63,14 +64,18 @@ int fwts_firmware_features(void)
>  {
>  	int features = 0;
>  
> -	/* we just have static feature definitions for now */
> +	/* we check for IPMI presence dynamically to assure available */
> +
> +	if (fwts_ipmi_present())
> +		features = FWTS_FW_FEATURE_IPMI;
> +

I'd probably do this after the switch (fwts_firmware_detect())
statement; that assigns the base features, then we can OR-in more
non-type-specific features with these checks.

So, we'd do something like:

	switch (fwts_firmware_detect()) {
	case FWTS_FIRMWARE_BIOS:
	case FWTS_FIRMWARE_UEFI:
		features = FWTS_FW_FEATURE_ACPI;
		break;
	case FWTS_FIRMWARE_OPAL:
		features = FWTS_FW_FEATURE_DEVICETREE;
		break;
	default:
		break;
	}

	if (fwts_ipmi_present())
		features |= FWTS_FW_FEATURE_IPMI;

	if (fwts_other_new_feature_present())
		features |= FWTS_FW_FEATURE_NEW_THING;


> @@ -83,7 +88,7 @@ const char *fwts_firmware_feature_string(const int features)
>  {
>  	const int n = FWTS_ARRAY_LEN(feature_names);
>  	const char sep[] = ", ";
> -	static char str[50];
> +	static char str[60];

Did you hit the FWTS_ASSERT before adding this change? I would have
thought that 50 bytes was large enough to contain the new "IPMI"
string too (strlen("ACPI, devicetree, IPMI") + 1 == 22).

Or did I get the FWTS_ASSERT check wrong?


> diff --git a/src/lib/src/fwts_framework.c b/src/lib/src/fwts_framework.c
> index d0979c9..2faeb67 100644
> --- a/src/lib/src/fwts_framework.c
> +++ b/src/lib/src/fwts_framework.c
> @@ -593,16 +593,6 @@ static int fwts_framework_run_test(fwts_framework *fw, fwts_framework_test *test
>  
>  	fwts_framework_minor_test_progress(fw, 0, "");
>  
> -	if (!fwts_firmware_has_features(test->fw_features)) {
> -		int missing = test->fw_features & ~fwts_firmware_features();
> -		fwts_log_info(fw, "Test skipped, missing features: %s",
> -				fwts_firmware_feature_string(missing));
> -		fw->current_major_test->results.skipped +=
> -			test->ops->total_tests;
> -		fw->total.skipped += test->ops->total_tests;
> -		goto done;
> -	}
> -
>  	if ((test->flags & FWTS_FLAG_ROOT_PRIV) &&
>  	    (fwts_check_root_euid(fw, true) != FWTS_OK)) {
>  		fwts_log_error(fw, "Aborted test, insufficient privilege.");
> @@ -615,6 +605,16 @@ static int fwts_framework_run_test(fwts_framework *fw, fwts_framework_test *test
>  		goto done;
>  	}
>  
> +	if (!fwts_firmware_has_features(test->fw_features)) {
> +		int missing = test->fw_features & ~fwts_firmware_features();
> +		fwts_log_info(fw, "Test skipped, missing features: %s",
> +			fwts_firmware_feature_string(missing));
> +		fw->current_major_test->results.skipped +=
> +			test->ops->total_tests;
> +		fw->total.skipped += test->ops->total_tests;
> +		goto done;
> +	}
> +

If I'm reading it correctly, this change moves the feature check to
*after* the ROOT_PRIV check. Was that your intention? Do we need to do
that?

Or is that related to...

> +unsigned int fwts_ipmi_msg_id = 1;
> +static const char *fwts_ipmi_devnode = "/dev/ipmi0";
> +
> +bool fwts_ipmi_present(void) {
> +	return !access(fwts_ipmi_devnode, R_OK | W_OK);
> +}

Semantic nit: the platform supports IPMI if !access(..., R_OK); however,
we can only use it if W_OK.

So, the feature check should be on R_OK, but the test should require
ROOT_PRIV (or even better, we'd do another W_OK check in the test, as
the IPMI device may be writable by non-root...).

Cheers,


Jeremy



More information about the fwts-devel mailing list