[RFC/PATCH] ubi-utils: add ubiecdump tool
Guido Martínez
guido at vanguardiasur.com.ar
Fri May 22 11:32:44 PDT 2015
This utility allows to dump the erase counter of each PEB in the UBI
device for auditing and testing purposes. It prints one value per line,
using -1 for bad PEBs and when errors occur. This allows to do some
quick stats like:
$ ubidumpec -m 7 | sort -n | uniq -c
21 -1
682 8
130 9
538 10
....
where we see 21 bad blocks, 682 blocks with an EC of 8 and so on, or to
plot histograms automatically.
It can be invoked with either an attached ubi device (/dev/ubi0) or with
and MTD device that contains a UBI volume (-m 7).
Signed-off-by: Guido Martínez <guido at vanguardiasur.com.ar>
---
Hi, this new tools allow to do some easy auditing on the ECs of the UBI
device. It was inspired by the "Wear-leveling peculiarities" thread on
linux-mtd. It only support printing the ECs one-by-one, but I could
extend it to show basic statistics if there's interest for that.
Thanks!
Makefile | 3 +-
ubi-utils/.gitignore | 1 +
ubi-utils/ubidumpec.c | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 189 insertions(+), 1 deletion(-)
create mode 100644 ubi-utils/ubidumpec.c
diff --git a/Makefile b/Makefile
index eade234..96ad3a1 100644
--- a/Makefile
+++ b/Makefile
@@ -28,7 +28,8 @@ MTD_BINS = \
sumtool jffs2reader
UBI_BINS = \
ubiupdatevol ubimkvol ubirmvol ubicrc32 ubinfo ubiattach \
- ubidetach ubinize ubiformat ubirename mtdinfo ubirsvol ubiblock
+ ubidetach ubinize ubiformat ubirename mtdinfo ubirsvol ubiblock \
+ ubidumpec
BINS = $(MTD_BINS)
BINS += mkfs.ubifs/mkfs.ubifs
diff --git a/ubi-utils/.gitignore b/ubi-utils/.gitignore
index 19653a8..b0d8619 100644
--- a/ubi-utils/.gitignore
+++ b/ubi-utils/.gitignore
@@ -11,3 +11,4 @@
/ubirsvol
/ubiblock
/mtdinfo
+/ubidumpec
diff --git a/ubi-utils/ubidumpec.c b/ubi-utils/ubidumpec.c
new file mode 100644
index 0000000..6ed06e5
--- /dev/null
+++ b/ubi-utils/ubidumpec.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) Guido Martínez, 2014
+ *
+ * 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; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#define PROGRAM_NAME "ubidumpec"
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <getopt.h>
+
+#include <mtd_swab.h>
+#include <crc32.h>
+
+#include <libubi.h>
+#include <libmtd.h>
+#include "common.h"
+
+static const char *usage_str =
+PROGRAM_NAME " version " VERSION " - dump erase counters of UBI device\n"
+"\n"
+"usage: " PROGRAM_NAME " <ubi_device>\n"
+" " PROGRAM_NAME " -m <mtd_num>\n"
+"\n"
+"This program will dump the UBI erase counter for each PEB in the\n"
+"associated MTD volume, one per line. Values of -1 mean either a bad\n"
+"block or that an error ocurred when trying to read the UBI header.\n";
+
+static void usage()
+{
+ fprintf(stderr, "%s", usage_str);
+}
+
+static int mtd_num = -1;
+
+static const struct option long_options[] = {
+ {"mtdn", required_argument, 0, 'm'},
+ {"help", no_argument, 0, 'h'},
+ { 0 },
+};
+
+static int parse_opt(int argc, char *argv[])
+{
+ int c, idx;
+
+ while ((c = getopt_long(argc, argv, "m:h", long_options, &idx)) != -1) {
+ switch (c) {
+ case 'm':
+ mtd_num = atoi(optarg);
+ break;
+ case 'h':
+ usage();
+ exit(0);
+ case '?':
+ exit(1);
+ }
+ }
+
+ return 0;
+}
+
+static int ubi2mtd(char *ubi_node)
+{
+ struct ubi_dev_info ubi_devinfo;
+ libubi_t libubi;
+ int ret;
+
+ libubi = libubi_open();
+ if (!libubi) {
+ if (errno == 0)
+ errmsg("UBI is not present in the system");
+ sys_errmsg("cannot open libubi");
+ return -1;
+ }
+
+ ret = ubi_get_dev_info(libubi, ubi_node, &ubi_devinfo);
+ if (ret) {
+ errmsg("Cannot get info for UBI node %s", ubi_node);
+ libubi_close(libubi);
+ return -1;
+ }
+
+ libubi_close(libubi);
+
+ return ubi_devinfo.mtd_num;
+}
+
+int main(int argc, char *argv[])
+{
+ struct mtd_dev_info mtd_devinfo;
+ struct ubi_ec_hdr ec_hdr;
+ libmtd_t libmtd;
+ char mtd_node[80];
+ uint32_t crc;
+ int fd;
+ int ret, peb;
+ int err = 1;
+
+ if (argc < 2) {
+ usage();
+ return 1;
+ }
+
+ parse_opt(argc, argv);
+
+ libmtd = libmtd_open();
+ if (!libmtd) {
+ if (errno == 0)
+ errmsg("MTD is not present in the system");
+ sys_errmsg("cannot open libmtd");
+ return 1;
+ }
+
+ /*
+ * If the user didn't specify a MTD number, then we need to find it
+ * from the UBI node the user gave us
+ */
+ if (mtd_num < 0) {
+ mtd_num = ubi2mtd(argv[1]);
+ if (mtd_num < 0)
+ goto out;
+ }
+
+ ret = mtd_get_dev_info1(libmtd, mtd_num, &mtd_devinfo);
+ if (ret) {
+ errmsg("Can't get info for MTD device #%i", mtd_num);
+ goto out;
+ }
+
+ sprintf(mtd_node, "/dev/mtd%iro", mtd_num);
+ fd = open(mtd_node, O_RDONLY);
+ if (fd < 0) {
+ sys_errmsg("Can't open %s", mtd_node);
+ goto out;
+ }
+
+ for (peb = 0; peb < mtd_devinfo.eb_cnt; peb++) {
+ if (mtd_is_bad(&mtd_devinfo, fd, peb)) {
+ printf("-1\n");
+ continue;
+ }
+
+ ret = mtd_read(&mtd_devinfo, fd, peb, 0, &ec_hdr, sizeof ec_hdr);
+ if (ret) {
+ warnmsg("reading UBI header of PEB #%i failed", peb);
+ printf("-1\n");
+ continue;
+ }
+
+ if (be32_to_cpu(ec_hdr.magic) != UBI_EC_HDR_MAGIC) {
+ warnmsg("PEB %i has bad UBI magic", peb);
+ printf("-1\n");
+ continue;
+ }
+
+ crc = mtd_crc32(UBI_CRC32_INIT, &ec_hdr, UBI_EC_HDR_SIZE_CRC);
+ if (crc != be32_to_cpu(ec_hdr.hdr_crc)) {
+ warnmsg("PEB %i has corrupt header", peb);
+ printf("-1\n");
+ continue;
+ }
+
+ printf("%" PRIu64 "\n", be64_to_cpu(ec_hdr.ec));
+ }
+ err = 0;
+
+out:
+ libmtd_close(libmtd);
+ return err;
+}
--
2.1.4
More information about the linux-mtd
mailing list