All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boris Brezillon <boris.brezillon@free-electrons.com>
To: Richard Weinberger <richard@nod.at>
Cc: linux-mtd@lists.infradead.org, david.oberhollenzer@sigma-star.at
Subject: Re: [PATCH 3/8] mtd-utils: Add flash torture test utility
Date: Tue, 26 Apr 2016 10:13:49 +0200	[thread overview]
Message-ID: <20160426101349.31f0bc4c@bbrezillon> (raw)
In-Reply-To: <1461622409-14970-4-git-send-email-richard@nod.at>

On Tue, 26 Apr 2016 00:13:24 +0200
Richard Weinberger <richard@nod.at> wrote:

> From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
> 
> Basically a user space port of the mtd torture test kernel module. In
> addition to the block offset and count module parameters, the utility
> supports a block stride and can restore the block contents after test.
> 
> In contrast to the kernel module, the torture test is implemented by
> the libmtd mtd_toruture function and thus doesn't allow for similarly
> fine grained options on diagnostics.
> 
> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
> Signed-off-by: Richard Weinberger <richard@nod.at>
> ---
>  .gitignore                 |   1 +
>  Makefile                   |   2 +-
>  misc-utils/flash_torture.c | 240 +++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 242 insertions(+), 1 deletion(-)
>  create mode 100644 misc-utils/flash_torture.c
> 
> diff --git a/.gitignore b/.gitignore
> index 2aac52c..5b529d1 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -35,6 +35,7 @@
>  /jffsX-utils/mkfs.jffs2
>  /misc-utils/mtd_debug
>  /misc-utils/mtdpart
> +/misc-utils/flash_torture
>  /nand-utils/nanddump
>  /nand-utils/nandtest
>  /nand-utils/nandwrite
> diff --git a/Makefile b/Makefile
> index 977c9c5..af3d1fd 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -20,7 +20,7 @@ MISC_BINS = \
>  	ftl_format doc_loadbios ftl_check mtd_debug docfdisk \
>  	serve_image recv_image mtdpart flash_erase flash_lock \
>  	flash_unlock flash_otp_info flash_otp_dump flash_otp_lock \
> -	flash_otp_write flashcp
> +	flash_otp_write flashcp flash_torture
>  UBI_BINS = \
>  	ubiupdatevol ubimkvol ubirmvol ubicrc32 ubinfo ubiattach \
>  	ubidetach ubinize ubiformat ubirename mtdinfo ubirsvol ubiblock
> diff --git a/misc-utils/flash_torture.c b/misc-utils/flash_torture.c
> new file mode 100644
> index 0000000..b5625c8
> --- /dev/null
> +++ b/misc-utils/flash_torture.c
> @@ -0,0 +1,240 @@
> +/*
> + * Copyright (C) 2006-2008 Artem Bityutskiy
> + * Copyright (C) 2006-2008 Jarkko Lavinen
> + * Copyright (C) 2006-2008 Adrian Hunter
> + * Copyright (C) 2015 sigma star gmbh
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 as published by
> + * the Free Software Foundation.
> + *
> + * 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; see the file COPYING. If not, write to the Free Software
> + * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
> + *
> + *
> + * WARNING: this test program may kill your flash and your device. Do not
> + * use it unless you know what you do. Authors are not responsible for any
> + * damage caused by this program.
> + *
> + * Author: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
> + *
> + * Based on linux torturetest.c
> + * Authors: Artem Bityutskiy, Jarkko Lavinen, Adria Hunter
> + */
> +
> +#define PROGRAM_NAME "flash_torture"
> +
> +#define KEEP_CONTENTS 0x01
> +#define RUN_FOREVER 0x02
> +
> +#include <mtd/mtd-user.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <libmtd.h>
> +#include <signal.h>
> +#include <stdio.h>
> +#include <fcntl.h>
> +
> +#include "common.h"
> +
> +static int peb=-1, blocks=-1, skip=-1;
> +static struct mtd_dev_info mtd;
> +static sig_atomic_t flags=0;
> +static const char *mtddev;
> +static libmtd_t mtd_desc;
> +static int mtdfd;
> +
> +static void sighandler(int sig)
> +{
> +	if (sig == SIGINT || sig == SIGTERM || sig == SIGHUP)
> +		flags &= ~RUN_FOREVER;
> +}
> +
> +static void usage(int status)
> +{
> +	fputs(
> +	"Usage: "PROGRAM_NAME" [OPTIONS] <device>\n\n"
> +	"Options:\n"
> +	"  -h, --help         Display this help output\n"
> +	"  -b, --peb <num>    Start from this physical erase block\n"
> +	"  -c, --blocks <num> Number of erase blocks to torture\n"
> +	"  -s, --skip <num>   Number of erase blocks to skip\n"
> +	"  -k, --keep         Try to restore existing contents after test\n"
> +	"  -r, --repeate      Repeate the torture test indefinitely\n",
> +	status==EXIT_SUCCESS ? stdout : stderr);
> +	exit(status);
> +}
> +
> +static long read_num(int idx, int argidx, int argc, char **argv)
> +{
> +	char *end;
> +	long num;
> +
> +	if (argidx >= argc) {
> +		fprintf(stderr, "%s: missing argument\n", argv[idx]);
> +		exit(EXIT_FAILURE);
> +	}
> +
> +	num = strtol(argv[argidx], &end, 0);
> +
> +	if (!end || *end!='\0') {
> +		fprintf(stderr, "%s: expected integer argument\n", argv[idx]);
> +		exit(EXIT_FAILURE);
> +	}
> +	return num;
> +}
> +
> +static void process_options(int argc, char **argv)
> +{
> +	int i;
> +
> +	for (i=1; i<argc; ++i) {
> +		if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
> +			usage(EXIT_SUCCESS);
> +		} else if (!strcmp(argv[i], "--peb") || !strcmp(argv[i], "-b")) {
> +			if (peb >= 0)
> +				goto failmulti;
> +			peb = read_num(i, i+1, argc, argv);
> +			if (peb < 0)
> +				goto failarg;
> +			++i;
> +		} else if (!strcmp(argv[i], "--blocks") || !strcmp(argv[i], "-c")) {
> +			if (blocks > 0)
> +				goto failmulti;
> +			blocks = read_num(i, i+1, argc, argv);
> +			if (blocks <= 0)
> +				goto failarg;
> +			++i;
> +		} else if (!strcmp(argv[i], "--skip") || !strcmp(argv[i], "-s")) {
> +			if (skip >= 0)
> +				goto failmulti;
> +			skip = read_num(i, i+1, argc, argv);
> +			if (skip < 0)
> +				goto failarg;
> +			++i;
> +		} else if (!strcmp(argv[i], "--keep") || !strcmp(argv[i], "-k")) {
> +			if (flags & KEEP_CONTENTS)
> +				goto failmulti;
> +			flags |= KEEP_CONTENTS;
> +		} else if (!strcmp(argv[i], "--repeate") || !strcmp(argv[i], "-r")) {
> +			if (flags & RUN_FOREVER)
> +				goto failmulti;
> +			flags |= RUN_FOREVER;
> +		} else {
> +			if (mtddev)
> +				usage(EXIT_FAILURE);
> +			mtddev = argv[i];
> +		}
> +	}

Hm, why not using getopt_long() to parse the command line?

> +
> +	if (!mtddev)
> +		errmsg_die("No device specified!\n");
> +	if (peb < 0)
> +		peb = 0;
> +	if (skip < 0)
> +		skip = 0;
> +	if (blocks < 0)
> +		blocks = 1;
> +	return;
> +failmulti:
> +	fprintf(stderr, "'%s' specified more than once!\n", argv[i]);
> +	exit(EXIT_FAILURE);
> +failarg:
> +	fprintf(stderr, "Invalid argument for '%s'!\n", argv[i]);
> +	exit(EXIT_FAILURE);
> +}
> +
> +int main(int argc, char **argv)
> +{
> +	int i, eb, err, count = 0;
> +	char* is_bad = NULL;

	char *is_bad = NULL;

> +	void *old=NULL;
> +
> +	process_options(argc, argv);
> +
> +	mtd_desc = libmtd_open();
> +	if (!mtd_desc)
> +		return errmsg("can't initialize libmtd");
> +
> +	if (mtd_get_dev_info(mtd_desc, mtddev, &mtd) < 0)
> +		return errmsg("mtd_get_dev_info failed");
> +
> +	if (peb >= mtd.eb_cnt)
> +		return errmsg("Physical erase block %d is out of range!\n", peb);
> +
> +	if ((peb + (blocks - 1)*(skip + 1)) >= mtd.eb_cnt) {
> +		return errmsg("Given block range exceeds block count of %d!\n",
> +				mtd.eb_cnt);
> +	}

You can drop the curly braces here.

> +
> +	signal(SIGINT, sighandler);
> +	signal(SIGTERM, sighandler);
> +	signal(SIGHUP, sighandler);
> +
> +	if (flags & KEEP_CONTENTS) {
> +		old = xmalloc(mtd.eb_size);
> +	}

Ditto.

> +
> +	is_bad = xmalloc(blocks);
> +
> +	if ((mtdfd = open(mtddev, O_RDWR)) == -1) {
> +		perror(mtddev);
> +		free(is_bad);
> +		free(old);
> +		return EXIT_FAILURE;
> +	}
> +
> +	for (i = 0; i < blocks; ++i) {
> +		eb = peb + i * (skip + 1);
> +		is_bad[i] = mtd_is_bad(&mtd, mtdfd, eb);
> +		if (is_bad[i]) {
> +			fprintf(stderr, "PEB %d marked bad, will be skipped\n", eb);
> +		}

Ditto.

> +	}
> +
> +	do {
> +		for (i = 0; i < blocks; ++i) {
> +			if (is_bad[i])
> +				continue;
> +
> +			eb = peb + i * (skip + 1);
> +
> +			if (flags & KEEP_CONTENTS) {
> +				err = mtd_read(&mtd, mtdfd, eb, 0, old, mtd.eb_size);
> +				if (err) {
> +					fprintf(stderr, "Failed to create backup copy "
> +							"of PEB %d, skipping!\n", eb);
> +					continue;
> +				}
> +			}
> +
> +			if (mtd_torture(mtd_desc, &mtd, mtdfd, eb))
> +				fprintf(stderr, "Block %d failed torture test!\n", eb);
> +
> +			if (flags & KEEP_CONTENTS) {
> +				err = mtd_erase(mtd_desc, &mtd, mtdfd, eb);
> +				if (err) {
> +					fprintf(stderr, "mtd_erase failed for block %d!\n", eb);
> +					continue;
> +				}
> +				err = mtd_write(mtd_desc, &mtd, mtdfd, eb, 0,
> +						old, mtd.eb_size, NULL, 0, 0);
> +				if (err)
> +					fprintf(stderr, "Failed to restore block %d!\n", eb);
> +			}
> +		}
> +
> +		printf("Torture test iterations done: %d\n", ++count);
> +	} while (flags & RUN_FOREVER);
> +
> +	free(old);
> +	free(is_bad);
> +	close(mtdfd);
> +	return EXIT_SUCCESS;
> +}



-- 
Boris Brezillon, Free Electrons
Embedded Linux and Kernel engineering
http://free-electrons.com

  reply	other threads:[~2016-04-26  8:14 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-25 22:13 [RFC] Porting kernel MTD tests to user space Richard Weinberger
2016-04-25 22:13 ` [PATCH 1/8] mtd-utils: Fix return status in mtd_torture test function Richard Weinberger
2016-04-26  7:57   ` Boris Brezillon
2016-07-13 17:30   ` Brian Norris
2016-07-13 21:59     ` Richard Weinberger
2016-07-13 22:06       ` Brian Norris
2016-04-25 22:13 ` [PATCH 2/8] mtd-utils: Add multi-block erase function Richard Weinberger
2016-04-26  8:04   ` Boris Brezillon
2016-04-27  9:21     ` David Oberhollenzer
2016-04-27  9:27       ` Boris Brezillon
2016-04-25 22:13 ` [PATCH 3/8] mtd-utils: Add flash torture test utility Richard Weinberger
2016-04-26  8:13   ` Boris Brezillon [this message]
2016-04-26 14:34   ` Ezequiel Garcia
2016-04-27  9:28     ` David Oberhollenzer
2016-04-25 22:13 ` [PATCH 4/8] mtd-utils: Add flash stress test Utility Richard Weinberger
2016-04-26  8:18   ` Boris Brezillon
2016-04-26  9:22     ` Richard Weinberger
2016-04-26  9:47       ` Boris Brezillon
2016-04-27 16:38         ` Brian Norris
2016-04-25 22:13 ` [PATCH 5/8] mtd-utils: Add flash speed " Richard Weinberger
2016-04-25 22:13 ` [PATCH 6/8] mtd-utils: Add nand flash bit errors test Richard Weinberger
2016-04-25 22:13 ` [PATCH 7/8] mtd-utils: Add flash read test utility Richard Weinberger
2016-04-25 22:13 ` [PATCH 8/8] mtd-utils: Add nand page " Richard Weinberger
2016-04-26  3:13 ` [RFC] Porting kernel MTD tests to user space Ezequiel Garcia
2016-04-26  7:00   ` Richard Weinberger
2016-04-27 16:32     ` Brian Norris
2016-04-26  5:17 ` Artem Bityutskiy
2016-04-26  6:58   ` Richard Weinberger
2016-04-26  7:45 ` Boris Brezillon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160426101349.31f0bc4c@bbrezillon \
    --to=boris.brezillon@free-electrons.com \
    --cc=david.oberhollenzer@sigma-star.at \
    --cc=linux-mtd@lists.infradead.org \
    --cc=richard@nod.at \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.