ACK: [PATCH] [V3] opal/prd_info: Add OPAL Processor Recovery Diagnostics

Deb McLemore debmc at linux.vnet.ibm.com
Thu Jun 23 18:42:19 UTC 2016


Thanks to all for the tips and suggestions !

On 06/23/2016 01:40 PM, Colin Ian King wrote:
> On 23/06/16 18:48, Deb McLemore wrote:
>> We added a new capability to perform PRD integrity checks.
>> The OPAL PRD firmware tests will be run when the device tree
>> has the proper node configured.  Runtime checks will use the
>> opal-prd service to query the version of the opal-prd service to
>> confirm operational state.
>>
>> Signed-off-by: Deb McLemore <debmc at linux.vnet.ibm.com>
>> ---
>>   configure.ac                                       |   2 +
>>   .../arg-show-tests-0001/arg-show-tests-0001.log    |   1 +
>>   .../arg-show-tests-full-0001.log                   |   2 +
>>   src/Makefile.am                                    |   1 +
>>   src/lib/include/fwts_pipeio.h                      |   1 +
>>   src/lib/src/Makefile.am                            |   3 +-
>>   src/lib/src/fwts_pipeio.c                          |  29 +++
>>   src/opal/prd_info.c                                | 224 +++++++++++++++++++++
>>   8 files changed, 262 insertions(+), 1 deletion(-)
>>   create mode 100644 src/opal/prd_info.c
>>
>> diff --git a/configure.ac b/configure.ac
>> index 6ada384..e3e7512 100644
>> --- a/configure.ac
>> +++ b/configure.ac
>> @@ -63,6 +63,8 @@
>>   	  AC_CHECK_HEADERS([json/json.h])
>>   	  AC_CHECK_HEADERS([glib.h])
>>   	  AC_CHECK_HEADERS([gio/gio.h])
>> +	  AC_CHECK_HEADERS([asm/opal-prd.h])
>> +	  AM_CONDITIONAL([HAVE_ASM_OPAL_PRD_H], [test "x$ac_cv_header_asm_opal_prd_h" = "xyes"])
>>   	  #AC_CHECK_LIB(pcre, pcre_compile)
>>   	  AC_SEARCH_LIBS([fdt_check_header], [fdt], [
>>   		AC_DEFINE([HAVE_LIBFDT], [1], [Define if we have libfdt])
>> diff --git a/fwts-test/arg-show-tests-0001/arg-show-tests-0001.log b/fwts-test/arg-show-tests-0001/arg-show-tests-0001.log
>> index 4179090..1a76b9d 100644
>> --- a/fwts-test/arg-show-tests-0001/arg-show-tests-0001.log
>> +++ b/fwts-test/arg-show-tests-0001/arg-show-tests-0001.log
>> @@ -112,6 +112,7 @@ Batch tests:
>>    pcc             Processor Clocking Control (PCC) test.
>>    pciirq          PCI IRQ Routing Table test.
>>    pnp             BIOS Support Installation structure test.
>> + prd_info        OPAL Processor Recovery Diagnostics Info
>>    rsdp            RSDP Root System Description Pointer test.
>>    rsdt            RSDT Root System Description Table test.
>>    sbst            SBST Smart Battery Specification Table test.
>> diff --git a/fwts-test/arg-show-tests-full-0001/arg-show-tests-full-0001.log b/fwts-test/arg-show-tests-full-0001/arg-show-tests-full-0001.log
>> index 6784ed3..695c5d6 100644
>> --- a/fwts-test/arg-show-tests-full-0001/arg-show-tests-full-0001.log
>> +++ b/fwts-test/arg-show-tests-full-0001/arg-show-tests-full-0001.log
>> @@ -663,6 +663,8 @@ Batch tests:
>>     PCI IRQ Routing Table test.
>>    pnp             (1 test):
>>     PnP BIOS Support Installation structure test.
>> + prd_info        (1 test):
>> +  OPAL Processor Recovery Diagnostics Info
>>    rsdp            (1 test):
>>     RSDP Root System Description Pointer test.
>>    rsdt            (1 test):
>> diff --git a/src/Makefile.am b/src/Makefile.am
>> index 00cde32..100eaa3 100644
>> --- a/src/Makefile.am
>> +++ b/src/Makefile.am
>> @@ -128,6 +128,7 @@ fwts_SOURCES = main.c 				\
>>   	kernel/olog/olog.c			\
>>   	kernel/oops/oops.c 			\
>>   	kernel/version/version.c 		\
>> +	opal/prd_info.c				\
>>   	pci/aspm/aspm.c 			\
>>   	pci/crs/crs.c 				\
>>   	pci/maxreadreq/maxreadreq.c 		\
>> diff --git a/src/lib/include/fwts_pipeio.h b/src/lib/include/fwts_pipeio.h
>> index 9a874dd..8c1b664 100644
>> --- a/src/lib/include/fwts_pipeio.h
>> +++ b/src/lib/include/fwts_pipeio.h
>> @@ -41,6 +41,7 @@ int   fwts_pipe_close(const int fd, const pid_t pid);
>>   int   fwts_pipe_close2(const int in_fd, const int out_fd, const pid_t pid);
>>   int   fwts_pipe_exec(const char *command, fwts_list **list, int *status);
>>   int   fwts_exec(const char *command, int *status);
>> +int   fwts_exec2(const char *command, char **output);
>>   int   fwts_write_string_to_file(const fwts_framework *fw, FILE *file, const char *str);
>>   int   fwts_write_string_file(const fwts_framework *fw, const char *file_name, const char *str);
>>   int   fwts_read_file_first_line(const fwts_framework *fw, const char *file_name, char **line);
>> diff --git a/src/lib/src/Makefile.am b/src/lib/src/Makefile.am
>> index e96b75f..1b8fd74 100644
>> --- a/src/lib/src/Makefile.am
>> +++ b/src/lib/src/Makefile.am
>> @@ -19,7 +19,8 @@ libfwts_la_LDFLAGS = 			\
>>   libfwts_la_CPPFLAGS = $(AM_CPPFLAGS) -DACPI_DEBUG_OUTPUT
>>   
>>   if HAVE_LIBFDT
>> -dt_sources = fwts_devicetree.c
>> +dt_sources = \
>> +	fwts_devicetree.c
>>   endif
>>   
>>   #
>> diff --git a/src/lib/src/fwts_pipeio.c b/src/lib/src/fwts_pipeio.c
>> index b501f7b..f62621a 100644
>> --- a/src/lib/src/fwts_pipeio.c
>> +++ b/src/lib/src/fwts_pipeio.c
>> @@ -321,6 +321,35 @@ int fwts_exec(const char *command, int *status)
>>   }
>>   
>>   /*
>> + *	fwts_exec2()
>> + *	execute a command
>> + *	Return to the parent/caller the exit status from the command
>> + *	status is -1 if errors.
>> + */
>> +
>> +int fwts_exec2(const char *command, char **output)
>> +{
>> +	pid_t   pid;
>> +	int     status = -1, in_fd, out_fd;
>> +	ssize_t out_len;
>> +
>> +	if (fwts_pipe_open_rw(command, &pid,
>> +		&in_fd, &out_fd) < 0) {
>> +		return -1;
>> +	}
>> +
>> +	if (fwts_pipe_readwrite(in_fd,
>> +		command, sizeof(command),
>> +		out_fd, output, &out_len)) {
>> +		return -1;
>> +	}
>> +
>> +	status = fwts_pipe_close2(in_fd, out_fd, pid);
>> +
>> +	return status;
>> +}
>> +
>> +/*
>>    *  fwts_write_string_to_file()
>>    *	write a string to a file pointer
>>    *	Return FWTS_OK if writing worked, FWTS_ERROR if it failed.
>> diff --git a/src/opal/prd_info.c b/src/opal/prd_info.c
>> new file mode 100644
>> index 0000000..537d1ed
>> --- /dev/null
>> +++ b/src/opal/prd_info.c
>> @@ -0,0 +1,224 @@
>> +/*
>> + * 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.
>> + *
>> + */
>> +
>> +#include <fcntl.h>
>> +#include <sys/ioctl.h>
>> +
>> +#include "fwts.h"
>> +
>> +#ifdef HAVE_LIBFDT
>> +#include <libfdt.h>
>> +#endif
>> +
>> +#ifdef HAVE_ASM_OPAL_PRD_H
>> +#include <asm/opal-prd.h>
>> +#endif
>> +
>> +static const char *prd_devnode = "/dev/opal-prd";
>> +
>> +bool prd_present(int fwts_prd_flags) {
>> +	return !access(prd_devnode, fwts_prd_flags);
>> +}
>> +
>> +#ifdef HAVE_ASM_OPAL_PRD_H
>> +int prd_dev_query(fwts_framework *fw)
>> +{
>> +
>> +	int fd = 0;
>> +	struct opal_prd_info info;
>> +
>> +	if ((fd = open(prd_devnode, O_RDWR)) < 0) {
>> +		fwts_failed(fw, LOG_LEVEL_CRITICAL, "OPAL PRD Info",
>> +			"Cannot get data from the OPAL PRD "
>> +			" device interface,"
>> +			" check if opal-prd daemon may be in use "
>> +			"or check your user privileges.");
>> +		return FWTS_ERROR;
>> +	}
>> +
>> +	memset(&info, 0, sizeof(info));
>> +
>> +	if (ioctl(fd, OPAL_PRD_GET_INFO, &info)) {
>> +		close(fd);
>> +		fwts_failed(fw, LOG_LEVEL_CRITICAL, "OPAL PRD Info",
>> +			"Cannot get data from the"
>> +			" OPAL PRD device interface.");
>> +		return FWTS_ERROR;
>> +	} else {
>> +		fwts_log_info(fw, "OPAL PRD Version is %lu",
>> +			info.version);
>> +		close(fd);
>> +		return FWTS_OK;
>> +	}
>> +}
>> +#endif
>> +
>> +static int prd_service_check(fwts_framework *fw, int *restart)
>> +{
>> +	int rc = FWTS_OK, status = 0, stop_status = 0;
>> +	char *command = NULL;
>> +	char *output = NULL;
>> +
>> +	command = "systemctl status opal-prd.service 2>&1";
>> +	status = fwts_exec2(command, &output);
>> +
>> +	if (output)
>> +		free(output);
>> +
>> +	switch (status) {
>> +	case -1: /* status when nothing was successful */
>> +		fwts_failed(fw, LOG_LEVEL_HIGH, "OPAL PRD Info",
>> +			"Attempt was made to stop the "
>> +			"opal-prd.service but was not "
>> +			"successful. Try to "
>> +			"\"sudo systemctl stop "
>> +			"opal-prd.service\" and retry.");
>> +		rc = FWTS_ERROR;
>> +		goto out;
>> +	case 0: /* "running" */
>> +		command = "systemctl stop opal-prd.service 2>&1";
>> +		stop_status = fwts_exec2(command, &output);
>> +
>> +		if (output)
>> +			free(output);
>> +
>> +		switch (stop_status) {
>> +		case 0:
>> +                        *restart = 1;
>> +                        break;
>> +		default:
>> +                        fwts_failed(fw, LOG_LEVEL_HIGH, "OPAL PRD Info",
>> +                                "Attempt was made to stop the "
>> +                                "opal-prd.service but was not "
>> +                                "successful. Try to "
>> +                                "\"sudo systemctl stop "
>> +                                "opal-prd.service\" and retry.");
>> +                        rc = FWTS_ERROR;
>> +                        goto out;
>> +		}
>> +	default:
>> +		break;
>> +	}
>> +
>> +out:
>> +	return rc;
>> +}
>> +
>> +static int prd_restart(fwts_framework *fw)
>> +{
>> +	int status = 0;
>> +	char *command = NULL;
>> +	char *output = NULL;
>> +
>> +	command = "systemctl start opal-prd.service 2>&1";
>> +	status = fwts_exec2(command, &output);
>> +
>> +	if (output)
>> +		free(output);
>> +
>> +	if (status) {
>> +		fwts_log_info(fw, "OPAL PRD service (opal-prd.service)"
>> +			" was restarted after stopping it to allow "
>> +			"checks.  Please re-check since processing "
>> +			"was not able to be confirmed, "
>> +			"\"sudo systemctl status opal-prd.service\"");
>> +	} else {
>> +		fwts_log_info(fw, "OPAL PRD service (opal-prd.service)"
>> +			" was restarted after stopping it to allow "
>> +			"checks.  This is informational only, "
>> +			"no action needed.");
>> +	}
>> +
>> +	return status; /* ignored by caller */
>> +}
>> +
>> +static int prd_info_test1(fwts_framework *fw)
>> +{
>> +
>> +	int restart = 0;
>> +
>> +	if (prd_service_check(fw, &restart)) {
>> +		/* failures logged in subroutine */
>> +		return FWTS_ERROR;
>> +	}
>> +
>> +	if (!prd_present(R_OK | W_OK)) {
>> +		fwts_failed(fw, LOG_LEVEL_CRITICAL, "OPAL PRD Info",
>> +			"Cannot read and write to the OPAL PRD"
>> +			" device interface,"
>> +			" check your user privileges.");
>> +		return FWTS_ERROR;
>> +	}
>> +
>> +#ifdef HAVE_ASM_OPAL_PRD_H
>> +	if (prd_dev_query(fw)) {
>> +		/* failures logged in subroutine */
>> +		return FWTS_ERROR;
>> +	}
>> +#endif
>> +
>> +	if (restart) {
>> +		prd_restart(fw); /* ignore rc */
>> +	}
>> +
>> +	fwts_passed(fw, "OPAL PRD info passed.");
>> +
>> +	return FWTS_OK;
>> +}
>> +
>> +static int prd_info_init(fwts_framework *fw)
>> +{
>> +	if (fw->fdt) {
>> +#ifdef HAVE_LIBFDT
>> +		int node;
>> +		node = fdt_path_offset(fw->fdt,
>> +			"/ibm,opal/diagnostics");
>> +		if (node >= 0) {
>> +			if (!fdt_node_check_compatible(fw->fdt, node,
>> +				"ibm,opal-prd")) {
>> +				return FWTS_OK;
>> +			} else {
>> +				return FWTS_SKIP;
>> +			}
>> +		}
>> +#endif
>> +	} else {
>> +		fwts_log_info(fw, "The OPAL PRD device tree node"
>> +			" is not present so skipping test");
>> +		return FWTS_SKIP;
>> +	}
>> +
>> +	/* only run test when fdt node is confirmed */
>> +	return FWTS_SKIP;
>> +}
>> +
>> +static fwts_framework_minor_test prd_info_tests[] = {
>> +	{ prd_info_test1, "OPAL Processor Recovery Diagnostics Info" },
>> +	{ NULL, NULL }
>> +};
>> +
>> +static fwts_framework_ops prd_info_ops = {
>> +	.description = "OPAL Processor Recovery Diagnostics Info",
>> +	.init        = prd_info_init,
>> +	.minor_tests = prd_info_tests
>> +};
>> +
>> +FWTS_REGISTER("prd_info", &prd_info_ops, FWTS_TEST_EARLY,
>> +		FWTS_FLAG_BATCH | FWTS_FLAG_ROOT_PRIV)
>>
> That looks good to me. Passes the fwts "make check" tests and is clean
> on CoverityScan too. Thanks Deb.
>
> Acked-by: Colin Ian King <colin.king at canonical.com>
>

-- 
==========================================
Deb McLemore
IBM OpenPower - IBM Systems
(512) 286 9980

debmc at us.ibm.com
debmc at linux.vnet.ibm.com - (plain text)
==========================================




More information about the fwts-devel mailing list