ACK: [PATCH 2/4] opal: mem_info: Add OPAL MEM Info validation

Colin Ian King colin.king at canonical.com
Fri Nov 11 09:45:33 UTC 2016


On 11/11/16 04:02, Deb McLemore wrote:
> Check that the MEM devices are properly setup in the device tree.
> 
> Signed-off-by: Deb McLemore <debmc at linux.vnet.ibm.com>
> ---
>  src/Makefile.am     |   3 +
>  src/opal/mem_info.c | 448 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 451 insertions(+)
>  create mode 100644 src/opal/mem_info.c
> 
> diff --git a/src/Makefile.am b/src/Makefile.am
> index b2604e3..9c2975b 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -24,6 +24,8 @@ if HAVE_LIBFDT
>  dt_tests = \
>  	devicetree/dt_base/dt_base.c		\
>  	devicetree/dt_sysinfo/dt_sysinfo.c
> +mem_tests = \
> +	opal/mem_info.c
>  endif
>  
>  if HAVE_LIBFDT
> @@ -158,6 +160,7 @@ fwts_SOURCES = main.c 				\
>  	uefi/esrtdump/esrtdump.c		\
>  	uefi/esrt/esrt.c			\
>  	$(pci_tests)				\
> +	$(mem_tests)				\
>  	$(dt_tests)
>  
>  fwts_LDFLAGS = -lm `pkg-config --libs glib-2.0 gio-2.0`
> diff --git a/src/opal/mem_info.c b/src/opal/mem_info.c
> new file mode 100644
> index 0000000..749b422
> --- /dev/null
> +++ b/src/opal/mem_info.c
> @@ -0,0 +1,448 @@
> +/*
> + * Copyright (C) 2010-2016 Canonical
> + * Some of this work - Copyright (C) 2016 IBM
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
> + *
> + */
> +
> +#define _GNU_SOURCE /* added for asprintf */
> +#include <fcntl.h>
> +#include <sys/ioctl.h>
> +#include <stdio.h>
> +
> +#include "fwts.h"
> +
> +#include <libfdt.h>
> +
> +static int get_dimm_property(fwts_framework *fw,
> +			char *my_path,
> +			bool hex,
> +			char *property)
> +{
> +	int node, prop_len, failures = 0;
> +	const char *prop_buf;
> +	char *prop_string = NULL;
> +
> +	prop_string = strstr(my_path, "/memory-buffer");
> +	if (prop_string) {
> +		node = fdt_path_offset(fw->fdt, prop_string);
> +		if (node >= 0) {
> +			prop_buf = fdt_getprop(fw->fdt, node,
> +					property,
> +					&prop_len);
> +			if ((prop_len > 0) && (prop_buf)) {
> +				fwts_log_nl(fw);
> +				if ((hex) && (prop_len == 4)) {
> +					fwts_passed(fw, "OPAL MEM Info"
> +						" Property of \"%s\" for "
> +						"\"%s\" is "
> +						"\"0x%02X%02X%02X%02X\".",
> +						property,
> +						my_path,
> +						prop_buf[0],
> +						prop_buf[1],
> +						prop_buf[2],
> +						prop_buf[3]);
> +				} else if (!hex) {
> +					if (check_property_printable(fw,
> +						property,
> +						prop_buf,
> +						prop_len)) {
> +							failures ++;
> +					}
> +					fwts_passed(fw,
> +						"OPAL MEM Info Property of"
> +						" \"%s\" for \"%s\" "
> +						"is \"%s\".",
> +						property,
> +						my_path,
> +						prop_buf);
> +				} else {
> +					failures ++;
> +					fwts_log_nl(fw);
> +					fwts_failed(fw,
> +						LOG_LEVEL_CRITICAL,
> +						"OPAL MEM Info",
> +						"Property of \"%s\" for "
> +						"\"%s\" is not properly "
> +						"formatted. Check your "
> +						"installation for proper "
> +						" device tree nodes.",
> +						property,
> +						my_path);
> +				}
> +			} else {
> +				failures ++;
> +				fwts_log_nl(fw);
> +				fwts_failed(fw,
> +					LOG_LEVEL_CRITICAL,
> +					"OPAL MEM Info",
> +					"Property of \"%s\" for \"%s\" was not"
> +					" able to be retrieved. Check the "
> +					"installation for the MEM device "
> +					"config for missing nodes in the device"
> +					" tree if you expect MEM devices.",
> +					property,
> +					my_path);
> +			}
> +		} else {
> +			failures ++;
> +			fwts_log_nl(fw);
> +			fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +					"OPAL MEM Info",
> +					"Failed to get node for memory-buffer"
> +					" \"%s/%s\", please check the system"
> +					" for setup issues.",
> +					my_path, property);
> +		}
> +	} else {
> +		failures ++;
> +		fwts_log_nl(fw);
> +		fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +				"OPAL MEM Info",
> +				"Internal processing problem at strstr"
> +				" my_path of \"%s\" for \"%s\", please check"
> +				" the system for setup issues.",
> +				my_path,
> +				property);
> +	}
> +	if (failures) {
> +		return FWTS_ERROR;
> +	} else {
> +		return FWTS_OK;
> +	}
> +}
> +
> +static int process_dimm(fwts_framework *fw,
> +			char *my_string,
> +			char *my_dir)
> +{
> +	int count, i, failures = 0;
> +	struct dirent **namelist;
> +	bool found = false;
> +
> +	count = scandir(my_dir, &namelist, NULL, alphasort);
> +	if (count < 0) {
> +		fwts_log_nl(fw);
> +		fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +			"OPAL MEM Info",
> +			"Scan for MEM devices in '%s' is unable to find any "
> +			"candidates. Check the installation "
> +			"for the MEM device config for missing nodes"
> +			" in the device tree if you expect MEM devices.",
> +			my_dir);
> +		return FWTS_ERROR;
> +	}
> +
> +	for (i = 0; i < count; i++) {
> +		struct dirent *dirent;
> +		char *my_buffer;
> +		char *my_path;
> +
> +		dirent = namelist[i];
> +
> +		if (dirent->d_name[0] == '.' ||
> +			asprintf(&my_buffer,
> +				"%s",
> +				dirent->d_name) < 0) {
> +			/* asprintf must be last condition so when it */
> +			/* evaluates my_buffer gets allocated */
> +			free(namelist[i]);
> +			continue;
> +		}
> +
> +		if (strstr(my_buffer, my_string)) {
> +			found = true;
> +			if (asprintf(&my_path,
> +				"%s/%s",
> +				my_dir,
> +				my_buffer) < 0 ) {
> +				fwts_log_nl(fw);
> +				fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +						"OPAL MEM Info",
> +						"Internal"
> +						" processing problem at"
> +						" my_link \"%s\", please"
> +						" check the system for"
> +						" setup issues.",
> +						my_buffer);
> +				free(my_buffer);
> +				free(namelist[i]);
> +				continue;
> +			}
> +			if (get_dimm_property(fw, my_path, false,
> +						DT_PROPERTY_OPAL_SLOT_LOC)) {
> +				failures ++;
> +			}
> +
> +			if (get_dimm_property(fw, my_path, false,
> +						DT_PROPERTY_OPAL_PART_NUM)) {
> +				failures ++;
> +			}
> +
> +			if (get_dimm_property(fw, my_path, false,
> +						DT_PROPERTY_OPAL_SERIAL_NUM)) {
> +				failures ++;
> +			}
> +
> +			if (get_dimm_property(fw, my_path, true,
> +					DT_PROPERTY_OPAL_MANUFACTURER_ID)) {
> +				failures ++;
> +			}
> +
> +			if (get_dimm_property(fw, my_path, false,
> +						DT_PROPERTY_OPAL_STATUS)) {
> +				failures ++;
> +			}
> +			free(my_buffer);
> +			free(namelist[i]);
> +		}
> +	}
> +	free(namelist);
> +
> +	if (!found) {
> +		failures ++;
> +		fwts_log_nl(fw);
> +		fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +				"OPAL MEM Info",
> +				"No MEM devices (memory-buffer) were found"
> +				" in \"%s\".  Check the system for setup"
> +				" issues.",
> +				DT_FS_PATH);
> +	}
> +
> +	if (failures) {
> +		return FWTS_ERROR;
> +	} else {
> +		return FWTS_OK;
> +	}
> +}
> +
> +static int process_mba(fwts_framework *fw,
> +			char *my_string,
> +			char *my_dir)
> +{
> +	int count, i, failures = 0;
> +	struct dirent **namelist;
> +	bool found = false;
> +
> +	count = scandir(my_dir, &namelist, NULL, alphasort);
> +	if (count < 0) {
> +		fwts_log_nl(fw);
> +		fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +			"OPAL MEM Info",
> +			"Scan for MEM devices for \"%s\" in \"%s\" is"
> +			" unable to find any candidates. Check the"
> +			" installation for the MEM device config for missing"
> +			" nodes in the device tree if you expect MEM devices.",
> +			my_string,
> +			my_dir);
> +		return FWTS_ERROR;
> +	}
> +
> +	for (i = 0; i < count; i++) {
> +		struct dirent *dirent;
> +		char *my_buffer;
> +		char *my_path;
> +
> +		dirent = namelist[i];
> +
> +		if (dirent->d_name[0] == '.' ||
> +			asprintf(&my_buffer,
> +				"%s",
> +				dirent->d_name) < 0) {
> +			/* asprintf must be last condition so when it */
> +			/* evaluates my_buffer gets allocated */
> +			free(namelist[i]);
> +			continue;
> +		}
> +
> +		if (strstr(my_buffer, my_string)) {
> +			found = true;
> +			if (asprintf(&my_path,
> +				"%s/%s",
> +				my_dir,
> +				my_buffer) < 0 ) {
> +				fwts_log_nl(fw);
> +				fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +						"OPAL MEM Info",
> +						"Internal"
> +						" processing problem at"
> +						" my_link \"%s\", please"
> +						" check the system for"
> +						" setup issues.",
> +						my_buffer);
> +				free(my_buffer);
> +				free(namelist[i]);
> +				continue;
> +			}
> +			if (process_dimm(fw, "dimm", my_path)) {
> +				failures ++;
> +			}
> +			free(my_buffer);
> +			free(namelist[i]);
> +		}
> +	}
> +	free(namelist);
> +
> +	if (!found) {
> +		fwts_log_nl(fw);
> +		fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +			"OPAL MEM Info",
> +			"Failed to find any device"
> +			" tree nodes for mba at X from \"%s\"."
> +			" Check the installation "
> +			"for the MEM device config for missing nodes"
> +			" in the device tree if you expect MEM devices.",
> +			my_dir);
> +	}
> +
> +	if ((!found) || (failures)) {
> +		return FWTS_ERROR;
> +	} else {
> +		return FWTS_OK;
> +	}
> +
> +}
> +
> +static int get_linux_mem_devices(fwts_framework *fw)
> +{
> +	int count, i, failures = 0;
> +	struct dirent **namelist;
> +	bool found = false;
> +
> +	count = scandir(DT_FS_PATH, &namelist, NULL, alphasort);
> +	if (count < 0) {
> +		fwts_log_nl(fw);
> +		fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +			"OPAL MEM Info",
> +			"Scan for MEM devices in '%s' is unable to find any "
> +			"candidates. Check the installation "
> +			"for the MEM device config for missing nodes"
> +			" in the device tree if you expect MEM devices.",
> +			DT_FS_PATH);
> +		return FWTS_ERROR;
> +	}
> +
> +	fwts_log_nl(fw);
> +	fwts_log_info(fw, "STARTING checks of MEM devices");
> +
> +	for (i = 0; i < count; i++) {
> +		struct dirent *dirent;
> +		char *mem_buffer;
> +		char *mba_path;
> +
> +		dirent = namelist[i];
> +
> +		if (dirent->d_name[0] == '.' ||
> +			asprintf(&mem_buffer,
> +				"%s",
> +				dirent->d_name) < 0) {
> +			/* asprintf must be last condition so when it */
> +			/* evaluates mem_buffer gets allocated */
> +			free(namelist[i]);
> +			continue;
> +		}
> +
> +		if (strstr(mem_buffer, "memory-buffer")) {
> +			found = true;
> +			if (asprintf(&mba_path,
> +				"%s/%s",
> +				DT_FS_PATH,
> +				mem_buffer) < 0 ) {
> +				fwts_log_nl(fw);
> +				fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +						"OPAL MEM Info",
> +						"Internal"
> +						" processing problem at"
> +						" mem_buffer \"%s\", please"
> +						" check the system for"
> +						" setup issues.",
> +						mem_buffer);
> +				free(mem_buffer);
> +				free(namelist[i]);
> +				continue;
> +			}
> +			if (process_mba(fw, "mba", mba_path)) {
> +				failures ++;
> +			}
> +			free(mem_buffer);
> +			free(namelist[i]);
> +		}
> +	}
> +	free(namelist);
> +
> +	fwts_log_nl(fw);
> +	fwts_log_info(fw, "ENDING checks of MEM devices");
> +	fwts_log_nl(fw);
> +
> +	if (!found) {
> +		failures ++;
> +		fwts_failed(fw, LOG_LEVEL_CRITICAL,
> +				"OPAL MEM Info",
> +				"No MEM devices (memory-buffer at X) were found"
> +				" in \"%s\".  Check the system for setup"
> +				" issues.",
> +				DT_FS_PATH);
> +	}
> +
> +	if (failures) {
> +		return FWTS_ERROR;
> +	} else {
> +		return FWTS_OK;
> +	}
> +
> +}
> +
> +static int mem_info_test1(fwts_framework *fw)
> +{
> +
> +	if (get_linux_mem_devices(fw)) {
> +
> +		/* errors logged earlier */
> +		return FWTS_ERROR;
> +	} else {
> +		return FWTS_OK;
> +	}
> +}
> +
> +static int mem_info_init(fwts_framework *fw)
> +{
> +	if (fw->firmware_type != FWTS_FIRMWARE_OPAL) {
> +		fwts_skipped(fw,
> +			"The firmware type detected was not set"
> +			" to OPAL so skipping the OPAL PCI Info"
> +			" checks.");
> +		return FWTS_SKIP;
> +	} else {
> +		return FWTS_OK;
> +	}
> +}
> +
> +static fwts_framework_minor_test mem_info_tests[] = {
> +	{ mem_info_test1, "OPAL MEM Info" },
> +	{ NULL, NULL }
> +};
> +
> +static fwts_framework_ops mem_info_ops = {
> +	.description = "OPAL MEM Info",
> +	.init        = mem_info_init,
> +	.minor_tests = mem_info_tests
> +};
> +
> +FWTS_REGISTER_FEATURES("mem_info", &mem_info_ops, FWTS_TEST_ANYTIME,
> +		FWTS_FLAG_BATCH | FWTS_FLAG_ROOT_PRIV,
> +		FWTS_FW_FEATURE_DEVICETREE);
> 
Acked-by: Colin Ian King <colin.king at canonical.com>



More information about the fwts-devel mailing list