From 725a91ea5ee4914a5187f26f18372062733bf036 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Sun, 23 Dec 2007 20:31:23 +0200 Subject: ubi-utils: move ubi_jffs2_test.sh to better place ... to tests/ubi-tests/ Signed-off-by: Artem Bityutskiy --- tests/ubi-tests/Makefile | 64 ++--- tests/ubi-tests/helpers/ubiupdatevol.c | 335 +++++++++++++++++++++++++++ tests/ubi-tests/io_update.c | 2 +- tests/ubi-tests/ubi_jffs2_test.sh | 407 ++++++++++++++++++++++++++++++++ ubi-utils/Makefile | 5 +- ubi-utils/scripts/ubi_jffs2_test.sh | 411 --------------------------------- ubi-utils/src/ubiupdatevol.c | 336 --------------------------- 7 files changed, 782 insertions(+), 778 deletions(-) create mode 100644 tests/ubi-tests/helpers/ubiupdatevol.c create mode 100755 tests/ubi-tests/ubi_jffs2_test.sh delete mode 100755 ubi-utils/scripts/ubi_jffs2_test.sh delete mode 100644 ubi-utils/src/ubiupdatevol.c diff --git a/tests/ubi-tests/Makefile b/tests/ubi-tests/Makefile index a2a49d0..a15d93c 100644 --- a/tests/ubi-tests/Makefile +++ b/tests/ubi-tests/Makefile @@ -1,41 +1,47 @@ -UBIUTILS=../../ubi-utils -INCLUDE1=$(UBIUTILS)/inc -INCLUDE2=../../include -LIB=. +LIBUBI_PATH=../../ubi-utils/ +LIBUBI_SRC_PATH=../../ubi-utils/src +LIBUBI_HEADER_PATH=../../ubi-utils/inc +UBIUTILS_PATH=../../ubi-utils/ CC := $(CROSS)gcc -ALL_FILES=libubi io_update rmvol integ -ALL_FILES+=io_paral io_read io_basic mkvol_basic mkvol_bad mkvol_paral rsvol +TESTS=io_update rmvol integ io_paral io_read io_basic \ + mkvol_basic mkvol_bad mkvol_paral rsvol -CFLAGS += -Wall -I$(INCLUDE1) -I$(INCLUDE2) -L$(LIB) -ggdb +HELPER_NAMES=ubiupdatevol +HELPERS=$(addprefix helpers/, $(HELPER_NAMES)) -all: $(ALL_FILES) +# Because of implicite rules we use make treats .o files as intermediate, thus +# it removes the. If you want to prevent the removal, uncomment the below +#.SECONDARY: $(addsuffix .o, $(TESTS)) $(addsuffix .o, $(HELPERS)) -libubi: $(UBIUTILS)/src/libubi.c $(UBIUTILS)/inc/libubi.h $(UBIUTILS)/src/libubi_int.h - $(CC) $(CFLAGS) -DUDEV_SETTLE_HACK -c $(UBIUTILS)/src/libubi.c -o libubi.o +CFLAGS += -Wall -I$(LIBUBI_HEADER_PATH) -L $(LIBUBI_PATH) -O0 -ggdb + +all: ubi-utils libubi $(TESTS) $(HELPERS) + +# Compile ubilib with the udevsettle hack +libubi: $(LIBUBI_SRC_PATH)/libubi.c $(LIBUBI_HEADER_PATH)/libubi.h $(LIBUBI_SRC_PATH)/libubi_int.h + $(CC) $(CFLAGS) -I $(LIBUBI_SRC_PATH) -DUDEV_SETTLE_HACK -c $(LIBUBI_SRC_PATH)/libubi.c -o libubi.o ar cr libubi.a libubi.o -io_paral: io_paral.c common.c - $(CC) $(CFLAGS) $^ -lubi -lpthread -o $@ -io_update: io_update.c common.c - $(CC) $(CFLAGS) $^ -lubi -o $@ -io_read: io_read.c common.c - $(CC) $(CFLAGS) $^ -lubi -o $@ -io_basic: io_basic.c common.c - $(CC) $(CFLAGS) $^ -lubi -o $@ -mkvol_basic: mkvol_basic.c common.c - $(CC) $(CFLAGS) $^ -lubi -o $@ -mkvol_bad: mkvol_bad.c common.c +# The below cancels existing implicite rule to make programs from .c files, +# in order to force make using our rule defined below +%: %.c + +# The below is the rule to get an .o file from a .c file +%.o: %.c + $(CC) $(CFLAGS) $< -c -o $@ + +# And the below is the rule to get final test executable from its .o and common.o +%: %.o common.o $(CC) $(CFLAGS) $^ -lubi -o $@ -mkvol_paral: mkvol_paral.c common.c + +# *paral tests require libpthread, thus the below rule for them +%paral: %paral.o common.o $(CC) $(CFLAGS) $^ -lubi -lpthread -o $@ -rsvol: rsvol.c common.c - $(CC) $(CFLAGS) $^ -lubi -o $@ -rmvol: rmvol.c common.c - $(CC) $(CFLAGS) $^ -lubi -o $@ -integ: integ.c - $(CC) $(CFLAGS) $^ -lubi -o $@ + +ubi-utils: + make -C $(UBIUTILS_PATH) clean: - rm -rf $(ALL_FILES) $(addsuffix .o, $(ALL_FILES)) + rm -f $(TESTS) $(addsuffix .o, $(TESTS)) libubi.* $(HELPERS) $(addsuffix .o, $(HELPERS)) diff --git a/tests/ubi-tests/helpers/ubiupdatevol.c b/tests/ubi-tests/helpers/ubiupdatevol.c new file mode 100644 index 0000000..6863e2a --- /dev/null +++ b/tests/ubi-tests/helpers/ubiupdatevol.c @@ -0,0 +1,335 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * An utility to update UBI volumes. + * + * Author: Frank Haverkamp + * Joshua W. Boyer + * + * 1.0 Reworked the userinterface to use argp. + * 1.1 Removed argp parsing because we want to use uClib. + * 1.2 Minor cleanups + * 1.3 Use a different libubi + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define PROGRAM_VERSION "1.3" + +#define MAXPATH 1024 +#define BUFSIZE 128 * 1024 +#define MIN(x,y) ((x)<(y)?(x):(y)) + +struct args { + int devn; + int vol_id; + int truncate; + int broken_update; + int bufsize; + + /* special stuff needed to get additional arguments */ + char *arg1; + char **options; /* [STRING...] */ +}; + +static struct args myargs = { + .devn = -1, + .vol_id = -1, + .truncate = 0, + .broken_update = 0, + .bufsize = BUFSIZE, + .arg1 = NULL, + .options = NULL, +}; + +static int verbose = 0; + +static char doc[] = "\nVersion: " PROGRAM_VERSION "\n" + "ubiupdatevol - write to UBI Volume.\n"; + +static const char *optionsstr = +" -B, --broken-update broken update, this is for testing\n" +" -d, --devn= UBI device\n" +" -n, --vol_id= UBI volume id\n" +" -t, --truncate truncate volume\n" +" -?, --help Give this help list\n" +" --usage Give a short usage message\n" +" -V, --version Print program version\n"; + +static const char *usage = +"Usage: ubiupdatevol [-Bt?V] [-d ] [-n ] [--broken-update]\n" +" [--devn=] [--vol_id=] [--truncate] [--help]\n" +" [--usage] [--version] \n"; + +struct option long_options[] = { + { .name = "broken-update", .has_arg = 0, .flag = NULL, .val = 'B' }, + { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, + { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, + { .name = "truncate", .has_arg = 0, .flag = NULL, .val = 't' }, + { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' }, + { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 }, + { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, + { NULL, 0, NULL, 0} +}; + +/* + * @brief Parse the arguments passed into the test case. + */ +static int +parse_opt(int argc, char **argv, struct args *args) +{ + while (1) { + int key; + + key = getopt_long(argc, argv, "Bd:n:t?V", long_options, NULL); + if (key == -1) + break; + + switch (key) { + case 'v': /* --verbose= */ + verbose = strtoul(optarg, (char **)NULL, 0); + break; + + case 'n': /* --vol_id= */ + args->vol_id = strtol(optarg, (char **)NULL, 0); + break; + + case 'd': /* --devn= */ + args->devn = strtol(optarg, (char **)NULL, 0); + break; + + case 'b': /* --bufsize= */ + args->bufsize = strtol(optarg, (char **)NULL, 0); + if (args->bufsize <= 0) + args->bufsize = BUFSIZE; + break; + + case 't': /* --truncate */ + args->truncate = 1; + break; + + case 'B': /* --broken-update */ + args->broken_update = 1; + break; + + case '?': /* help */ + fprintf(stderr, "Usage: " + "ubiupdatevol [OPTION...] \n%s%s\n", + doc, optionsstr); + exit(EXIT_SUCCESS); + break; + + case 'V': + fprintf(stderr, "%s\n", PROGRAM_VERSION); + exit(0); + break; + + default: + fprintf(stderr, "%s", usage); + exit(EXIT_FAILURE); + } + } + + if (optind < argc) { + /* only one additional argument required */ + args->arg1 = argv[optind++]; + } + return 0; +} + +/** + * @bytes bytes must be always 0, if not 0 this is a testcase for a + * broken volume update where data is promissed to be written, but for + * some reason nothing is written. The volume is unusable after this. + */ +static int +ubi_truncate_volume(struct args *args, int64_t bytes,libubi_t libubi) +{ + int rc, ofd; + char path[MAXPATH]; + int old_errno; + + snprintf(path, MAXPATH-1, "/dev/ubi%d_%d", args->devn, args->vol_id); + path[MAXPATH-1] = '\0'; + + ofd = open(path, O_RDWR); + if (ofd < 0) { + fprintf(stderr, "Cannot open volume %s\n", path); + perror("open"); + exit(EXIT_FAILURE); + } + rc = ubi_update_start(libubi, ofd, bytes); + old_errno = errno; + if (rc < 0) { + perror("UBI volume update ioctl"); + fprintf(stderr, " rc=%d errno=%d\n", rc, old_errno); + exit(EXIT_FAILURE); + } + close(ofd); + return 0; +} + +static ssize_t ubi_write(int fd, const void *buf, size_t count) +{ + int rc; + int len = count; + + while (len) { + rc = write(fd, buf, len); + if (rc == -1) { + if (errno == EINTR) + continue; /* try again */ + perror("write error"); + return rc; + } + + len -= rc; + buf += rc; + } + return count; +} + +static int +ubi_update_volume(struct args *args, libubi_t libubi) +{ + int rc, ofd; + FILE *ifp = NULL; + struct stat st; + int size = 0; + char *fname = args->arg1; + char path[MAXPATH]; + char *buf; + int64_t bytes = 0; + int old_errno; + + buf = malloc(args->bufsize); + if (!buf) { + perror("Out of memory"); + exit(EXIT_FAILURE); + } + + if (fname == NULL) { + fprintf(stderr, "Please specify an existing image file.\n"); + exit(EXIT_FAILURE); + } + + rc = stat(fname, &st); + if (rc < 0) { + fprintf(stderr, "Cannot stat input file %s\n", fname); + exit(EXIT_FAILURE); + } + bytes = size = st.st_size; + + ifp = fopen(fname, "r"); + if (!ifp) + exit(EXIT_FAILURE); + + snprintf(path, MAXPATH-1, "/dev/ubi%d_%d", args->devn, args->vol_id); + path[MAXPATH-1] = '\0'; + + ofd = open(path, O_RDWR); + if (ofd < 0) { + fprintf(stderr, "Cannot open UBI volume %s\n", path); + exit(EXIT_FAILURE); + } + + rc = ubi_update_start(libubi, ofd, bytes); + old_errno = errno; + if (rc < 0) { + perror("UBI volume update ioctl"); + fprintf(stderr, " rc=%d errno=%d\n", rc, old_errno); + exit(EXIT_FAILURE); + } + + while (size > 0) { + ssize_t tocopy = MIN(args->bufsize, size); + + rc = fread(buf, tocopy, 1, ifp); + if (rc != 1) { + perror("Could not read everything."); + exit(EXIT_FAILURE); + } + + rc = ubi_write(ofd, buf, tocopy); + old_errno = errno; + if (rc != tocopy) { + perror("Could not write to device"); + fprintf(stderr, " rc=%d errno=%d\n", rc, old_errno); + exit(EXIT_FAILURE); + } + size -= tocopy; + } + + free(buf); + fclose(ifp); + rc = close(ofd); + if (rc != 0) { + perror("UBI volume close failed"); + exit(EXIT_FAILURE); + } + return 0; +} + +int +main(int argc, char *argv[]) +{ + int rc; + libubi_t libubi; + + parse_opt(argc, argv, &myargs); + + libubi = libubi_open(); + if (libubi == NULL) { + perror("Cannot open libubi"); + return -1; + } + + if (myargs.truncate) { + rc = ubi_truncate_volume(&myargs, 0LL, libubi); + if (rc < 0) + goto out_libubi; + } + else if (myargs.broken_update) { + rc = ubi_truncate_volume(&myargs, 1LL, libubi); + if (rc < 0) + goto out_libubi; + } else { + rc = ubi_update_volume(&myargs, libubi); + if (rc < 0) + goto out_libubi; + } + + libubi_close(libubi); + return 0; + +out_libubi: + libubi_close(libubi); + return -1; +} diff --git a/tests/ubi-tests/io_update.c b/tests/ubi-tests/io_update.c index 543cb8c..4f8a374 100644 --- a/tests/ubi-tests/io_update.c +++ b/tests/ubi-tests/io_update.c @@ -185,7 +185,7 @@ static int test_update1(struct ubi_vol_info *vol_info) } for (i = 0; i < SEQ_SZ; i++) { - int ret, stop = 0, len; + int ret, stop = 0, len = 0; off_t off = 0; unsigned char buf1[vol_info->rsvd_bytes]; diff --git a/tests/ubi-tests/ubi_jffs2_test.sh b/tests/ubi-tests/ubi_jffs2_test.sh new file mode 100755 index 0000000..a6172ba --- /dev/null +++ b/tests/ubi-tests/ubi_jffs2_test.sh @@ -0,0 +1,407 @@ +#!/bin/sh +# +# UBI Volume creation/deletion/write/read and JFFS2 on top of UBI +# testcases. +# +# Written in shell language to reduce dependencies to more sophisticated +# interpreters, which may not be available on some stupid platforms. +# +# Author: Frank Haverkamp +# +# 1.0 Initial version +# 1.1 Added fixup for delayed device node creation by udev +# This points to a problem in the tools, mabe in the desing +# Tue Oct 31 14:14:54 CET 2006 +# + +# Make sure we have UBI utilities in the PATH +export PATH=../../ubi-utils:$PATH + +VERSION="1.1" +ITERATIONS=250 +ALIGNMENT=2048 + +UBIMKVOL="ubimkvol" +UBIRMVOL="ubirmvol" +# This test script uses special program to update volumes +UBIUPDATEVOL="helpers/ubiupdatevol" + +SIZE_512K=524288 +SIZE_1M=1310720 + +MINVOL=10 +MAXVOL=12 + +TLOG=/dev/null + +# +# To have a standardized output I define the following function to be +# used when a test was ok or when it failed. +# +failed () +{ + echo "FAILED" +} + +passed () +{ + echo "PASSED" +} + +# +# Print sucess message. Consider to exit with zero as return code. +# +exit_success () +{ + echo "SUCCESS" + exit 0 +} + +# +# Print failure message. Consider to exit with non zero return code. +# +exit_failure () +{ + echo "FAILED" + exit 1 +} + +############################################################################### +# +# START +# +############################################################################### + +fix_sysfs_issue () +{ + echo "*** Fixing the sysfs issue with the /dev nodes ... " + + minor=0 + major=`grep ubi0 /proc/devices | sed -e 's/\(.*\) ubi0/\1/'` + + rm -rf /dev/ubi0 + mknod /dev/ubi0 c $major 0 + + for minor in `seq $MINVOL $MAXVOL`; do + echo " -> mknod /dev/ubi0_$minor c $major $(($minor + 1))" + rm -rf /dev/ubi0_$minor + mknod /dev/ubi0_$minor c $major $(($minor + 1)) + done + passed +} + +# +# Wait for while udev creates device nodes +# +udev_wait () +{ + udevsettle || sleep 2; +} + +# delete_volume - Delete a volume. If it does not exist, do not try +# to delete it. +# @id: volume id +# +delete_volume () +{ + volume=$1 + + ### FIXME broken sysfs!!!! + if [ -e /sys/class/ubi/$volume -o \ + -e /sys/class/ubi/ubi0/$volume -o \ + -e /sys/class/ubi/ubi0_$volume ]; then + + echo "*** Truncate volume if it exists ... " + echo " $UBIUPDATEVOL -d0 -n$volume -t" + $UBIUPDATEVOL -d0 -n$volume -t + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + + echo -n "*** Delete volume if it exists ... " + $UBIRMVOL $UBI_DEVICE -n$volume + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + # udev_wait + fi +} + +# writevol_test - Tests volume creation and writing data to it. +# +# @volume: Volume number +# @size: Size of random data to write +# @type: Volume type static or dynamic +# +writevol_test () +{ + volume=$1 + size=$2 + type=$3 + + echo "*** Write volume test with size $size" + +### Make sure that volume exist, delete existing volume, create new + + delete_volume $volume + + echo "*** Try to create volume" + echo " $UBIMKVOL $UBI_DEVICE -a $ALIGNMENT -n$volume -t$type -NNEW$volume -s $size ... " + $UBIMKVOL $UBI_DEVICE -n$volume -t$type -N"NEW$volume" -s $size + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + udev_wait + +### Try to create same volume again + echo -n "*** Try to create some volume again, this must fail ... " + $UBIMKVOL $UBI_DEVICE -a $ALIGNMENT -n$volume -t$type -N"NEW$volume" -s $size + if [ $? -eq "0" ] ; then + exit_failure + fi + passed + +### Now create test data, write it, read it, compare it + echo -n "*** Create test data ... " + dd if=/dev/urandom of=testdata.bin bs=$size count=1 + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + + echo "*** Now writing data to volume ... " + echo " $UBIUPDATEVOL -d0 -n$volume testdata.bin" + ls -l testdata.bin + $UBIUPDATEVOL -d0 -n$volume testdata.bin + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + + echo "*** Download data with dd bs=1 ... " + dd if=/dev/ubi0_$volume of=readdata.bin bs=$size count=1 + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + + echo -n "*** Comparing data ... " + cmp readdata.bin testdata.bin + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + + echo -n "*** Now truncate volume ... " + $UBIUPDATEVOL -d0 -n$volume -t + if [ $? -ne "0" ] ; then + exit_failure + fi + passed +} + +jffs2_torture () +{ + cat /dev/null > TLOG + + echo "*** Torture test ... " + + for i in `seq $iterations`; do + dd if=/dev/urandom of=test.bin bs=$i count=1 2>> $TLOG + if [ $? -ne "0" ] ; then + echo "Testing $i byte (dd if=/dev/urandom of=foo bs=$i count=1) ... " + exit_failure + fi + #passed + + dd if=test.bin of=new.bin bs=$i count=1 2>> $TLOG + if [ $? -ne "0" ] ; then + echo "dd if=test.bin of=new.bin bs=$i count=1 2>> $TLOG" + exit_failure + fi + #passed + + #echo "Comparing files ... " + cmp test.bin new.bin + dd if=test.bin of=new.bin bs=$i count=1 2>> $TLOG + if [ $? -ne "0" ] ; then + exit_failure + fi + #passed + #echo -n "." + done + + echo -n "step0:ok " + + for i in `seq $iterations`; do + dd if=/dev/urandom of=foo bs=$i count=1 2>> $TLOG + if [ $? -ne "0" ] ; then + echo "Testing $i byte (dd if=/dev/urandom of=foo bs=$i count=1) ... " + exit_failure + fi + #passed + done + + echo -n "step1:ok " + + for i in `seq $iterations`; do + dd if=/dev/zero of=foo bs=1 count=$i 2>> $TLOG + if [ $? -ne "0" ] ; then + echo "Testing $i byte (dd if=/dev/zero of=foo bs=1 count=$i) ... " + exit_failure + fi + #passed + done + + echo -n "step2:ok " + + for i in `seq $iterations`; do + dd if=/dev/zero of=foo bs=$i count=16 2>> $TLOG + if [ $? -ne "0" ] ; then + echo "Testing $i byte (dd if=/dev/zero of=foo bs=$i count=1024) ... " + exit_failure + fi + #passed + done + + echo -n "step3:ok " + + passed +} + +# writevol_test - Tests volume creation and writing data to it. +# +# @volume: Volume number +# @size: Size of random data to write +# @type: Volume type static or dynamic +# +jffs2_test () +{ + name=$1 + iterations=$2 + directory=`pwd` + + ### Setup + ulimit -c unlimited + + echo -n "*** Create directory /mnt/$name ... " + mkdir -p /mnt/$name + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + + echo -n "*** mount -t jffs2 mtd:$name /mnt/$name ... " + mount -t jffs2 mtd:$name /mnt/$name + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + + echo -n "*** change directory ... " + cd /mnt/$name + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + + ls + echo "*** list directory ... " + ls -la + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + + ### Torture + echo -n "*** touch I_WAS_HERE ... " + touch I_WAS_HERE + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + + jffs2_torture + + echo "*** list directory ... " + ls -la + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + + ### Cleanup + echo -n "*** go back ... " + cd $directory + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + + ### Still mounted, ubiupdatevol must fail! + + echo -n "*** $UBIUPDATEVOL -d0 -n$volume -t must fail! ..." + $UBIUPDATEVOL -d0 -n$volume -t + if [ $? -eq "0" ] ; then + exit_failure + fi + passed + + echo -n "*** umount /mnt/$name ... " + umount /mnt/$name + if [ $? -ne "0" ] ; then + exit_failure + fi + passed + + return +} + +echo "***********************************************************************" +echo "* UBI JFFS2 Testing starts now ... *" +echo "* Good luck! *" +echo "***********************************************************************" +echo "VERSION: $VERSION" + +# Set to zero if not running on example hardware +grep ubi /proc/devices > /dev/null +if [ $? -ne "0" ]; then + echo "No UBI found in /proc/devices! I am broken!" + exit_failure +fi + +if [ "x$1" == "x" ]; then + echo "Please, specify ubi device to test, e.g., $0 /dev/ubi0"; + exit_failure; +fi + +UBI_DEVICE=$1 + +# Set to zero if not running on example hardware +grep 1142 /proc/cpuinfo > /dev/null +if [ $? -eq "0" ]; then + echo "Running on example hardware" + mount -o remount,rw / / + sleep 1 + fix_sysfs_issue +else + echo "Running on Artems hardware" +fi + +for volume in `seq $MINVOL $MAXVOL`; do + echo -n "************ VOLUME $volume NEW$volume " + echo "******************************************" + writevol_test $volume $SIZE_1M dynamic + jffs2_test NEW$volume $ITERATIONS + delete_volume $volume +done + +echo "***********************************************************************" +echo "* Congratulations, no errors found! *" +echo "* Have fun with your cool UBI system! *" +echo "***********************************************************************" + +exit_success diff --git a/ubi-utils/Makefile b/ubi-utils/Makefile index 6a0391f..abd5dc4 100644 --- a/ubi-utils/Makefile +++ b/ubi-utils/Makefile @@ -25,7 +25,7 @@ vpath %.c ./src %.o: %.c $(CC) $(CFLAGS) -g -c -o $@ $< -g -Wp,-MD,.$(shell basename $<).dep -all: $(TARGETS) +all: $(TARGETS) libubi IGNORE=${wildcard .*.c.dep} -include ${IGNORE} @@ -33,6 +33,9 @@ IGNORE=${wildcard .*.c.dep} clean: rm -rf *.o $(TARGETS) .*.c.dep +libubi: libubi.o + ar cr libubi.a libubi.o + ubinfo: ubinfo.o common.o libubi.o $(CC) $(LDFLAGS) -o $@ $^ diff --git a/ubi-utils/scripts/ubi_jffs2_test.sh b/ubi-utils/scripts/ubi_jffs2_test.sh deleted file mode 100755 index 883903d..0000000 --- a/ubi-utils/scripts/ubi_jffs2_test.sh +++ /dev/null @@ -1,411 +0,0 @@ -#!/bin/sh -# -# UBI Volume creation/deletion/write/read and JFFS2 on top of UBI -# testcases. -# -# Written in shell language to reduce dependencies to more sophisticated -# interpreters, which may not be available on some stupid platforms. -# -# Author: Frank Haverkamp -# -# 1.0 Initial version -# 1.1 Added fixup for delayed device node creation by udev -# This points to a problem in the tools, mabe in the desing -# Tue Oct 31 14:14:54 CET 2006 -# - -VERSION="1.1" - -export PATH=$PATH:/bin:~/bin:/usr/local/bin:/home/dedekind/work/prj/ubi/tools/flashutils/bin/ - -ITERATIONS=250 -ALIGNMENT=2048 - -UBIMKVOL="ubimkvol -a $ALIGNMENT" -UBIRMVOL=ubirmvol -UBIUPDATEVOL=ubiupdatevol - -SIZE_512K=524288 -SIZE_1M=1310720 - -MINVOL=10 -MAXVOL=12 - -TLOG=/dev/null - -# -# To have a standardized output I define the following function to be -# used when a test was ok or when it failed. -# -failed () -{ - echo "FAILED" -} - -passed () -{ - echo "PASSED" -} - -# -# Print sucess message. Consider to exit with zero as return code. -# -exit_success () -{ - echo "SUCCESS" - exit 0 -} - -# -# Print failure message. Consider to exit with non zero return code. -# -exit_failure () -{ - echo "FAILED" - exit 1 -} - -############################################################################### -# -# START -# -############################################################################### - -fix_sysfs_issue () -{ - echo "*** Fixing the sysfs issue with the /dev nodes ... " - - minor=0 - major=`grep ubi0 /proc/devices | sed -e 's/\(.*\) ubi0/\1/'` - - rm -rf /dev/ubi0 - mknod /dev/ubi0 c $major 0 - - for minor in `seq $MINVOL $MAXVOL`; do - echo " -> mknod /dev/ubi0_$minor c $major $(($minor + 1))" - rm -rf /dev/ubi0_$minor - mknod /dev/ubi0_$minor c $major $(($minor + 1)) - done - passed -} - -# -# FIXME Udev needs some time until the device nodes are created. -# This will cause trouble if after ubimkvol an update attempt -# is started immediately, since the device node is not yet -# available. We should either fix the tools with inotify or -# other ideas or figure out a different way to solve the problem -# e.g. to use ubi0 and make the volume device nodes obsolete... -# -udev_wait () -{ - echo -n "FIXME Waiting for udev to create/delete device node " - grep 2\.6\.5 /proc/version > /dev/null - if [ $? -eq "0" ]; then - for i in `seq 0 5`; do - sleep 1; echo -n "."; - done - echo " ok" - fi -} - -# delete_volume - Delete a volume. If it does not exist, do not try -# to delete it. -# @id: volume id -# -delete_volume () -{ - volume=$1 - - ### FIXME broken sysfs!!!! - if [ -e /sys/class/ubi/$volume -o \ - -e /sys/class/ubi/ubi0/$volume -o \ - -e /sys/class/ubi/ubi0_$volume ]; then - - echo "*** Truncate volume if it exists ... " - echo " $UBIUPDATEVOL -d0 -n$volume -t" - $UBIUPDATEVOL -d0 -n$volume -t - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - - echo -n "*** Delete volume if it exists ... " - $UBIRMVOL -d0 -n$volume - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - # udev_wait - fi -} - -# writevol_test - Tests volume creation and writing data to it. -# -# @volume: Volume number -# @size: Size of random data to write -# @type: Volume type static or dynamic -# -writevol_test () -{ - volume=$1 - size=$2 - type=$3 - - echo "*** Write volume test with size $size" - -### Make sure that volume exist, delete existing volume, create new - - delete_volume $volume - - echo "*** Try to create volume" - echo " $UBIMKVOL -d0 -n$volume -t$type -NNEW$volume -s $size ... " - $UBIMKVOL -d0 -n$volume -t$type -N"NEW$volume" -s $size - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - udev_wait - -### Try to create same volume again - echo -n "*** Try to create some volume again, this must fail ... " - $UBIMKVOL -d0 -n$volume -t$type -N"NEW$volume" -s $size - if [ $? -eq "0" ] ; then - exit_failure - fi - passed - -### Now create test data, write it, read it, compare it - echo -n "*** Create test data ... " - dd if=/dev/urandom of=testdata.bin bs=$size count=1 - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - - echo "*** Now writing data to volume ... " - echo " $UBIUPDATEVOL -d0 -n$volume testdata.bin" - ls -l testdata.bin - $UBIUPDATEVOL -d0 -n$volume testdata.bin - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - - echo "*** Download data with dd bs=1 ... " - dd if=/dev/ubi0_$volume of=readdata.bin bs=$size count=1 - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - - echo -n "*** Comparing data ... " - cmp readdata.bin testdata.bin - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - - echo -n "*** Now truncate volume ... " - $UBIUPDATEVOL -d0 -n$volume -t - if [ $? -ne "0" ] ; then - exit_failure - fi - passed -} - -jffs2_torture () -{ - cat /dev/null > TLOG - - echo "*** Torture test ... " - - for i in `seq $iterations`; do - dd if=/dev/urandom of=test.bin bs=$i count=1 2>> $TLOG - if [ $? -ne "0" ] ; then - echo "Testing $i byte (dd if=/dev/urandom of=foo bs=$i count=1) ... " - exit_failure - fi - #passed - - dd if=test.bin of=new.bin bs=$i count=1 2>> $TLOG - if [ $? -ne "0" ] ; then - echo "dd if=test.bin of=new.bin bs=$i count=1 2>> $TLOG" - exit_failure - fi - #passed - - #echo "Comparing files ... " - cmp test.bin new.bin - dd if=test.bin of=new.bin bs=$i count=1 2>> $TLOG - if [ $? -ne "0" ] ; then - exit_failure - fi - #passed - #echo -n "." - done - - echo -n "step0:ok " - - for i in `seq $iterations`; do - dd if=/dev/urandom of=foo bs=$i count=1 2>> $TLOG - if [ $? -ne "0" ] ; then - echo "Testing $i byte (dd if=/dev/urandom of=foo bs=$i count=1) ... " - exit_failure - fi - #passed - done - - echo -n "step1:ok " - - for i in `seq $iterations`; do - dd if=/dev/zero of=foo bs=1 count=$i 2>> $TLOG - if [ $? -ne "0" ] ; then - echo "Testing $i byte (dd if=/dev/zero of=foo bs=1 count=$i) ... " - exit_failure - fi - #passed - done - - echo -n "step2:ok " - - for i in `seq $iterations`; do - dd if=/dev/zero of=foo bs=$i count=16 2>> $TLOG - if [ $? -ne "0" ] ; then - echo "Testing $i byte (dd if=/dev/zero of=foo bs=$i count=1024) ... " - exit_failure - fi - #passed - done - - echo -n "step3:ok " - - passed -} - -# writevol_test - Tests volume creation and writing data to it. -# -# @volume: Volume number -# @size: Size of random data to write -# @type: Volume type static or dynamic -# -jffs2_test () -{ - name=$1 - iterations=$2 - directory=`pwd` - - ### Setup - ulimit -c unlimited - - echo -n "*** Create directory /mnt/$name ... " - mkdir -p /mnt/$name - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - - echo -n "*** mount -t jffs2 mtd:$name /mnt/$name ... " - mount -t jffs2 mtd:$name /mnt/$name - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - - echo -n "*** change directory ... " - cd /mnt/$name - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - - ls - echo "*** list directory ... " - ls -la - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - - ### Torture - echo -n "*** touch I_WAS_HERE ... " - touch I_WAS_HERE - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - - jffs2_torture - - echo "*** list directory ... " - ls -la - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - - ### Cleanup - echo -n "*** go back ... " - cd $directory - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - - ### Still mounted, ubiupdatevol must fail! - - echo -n "*** $UBIUPDATEVOL -d0 -n$volume -t must fail! ..." - $UBIUPDATEVOL -d0 -n$volume -t - if [ $? -eq "0" ] ; then - exit_failure - fi - passed - - echo -n "*** umount /mnt/$name ... " - umount /mnt/$name - if [ $? -ne "0" ] ; then - exit_failure - fi - passed - - return -} - -echo "***********************************************************************" -echo "* UBI JFFS2 Testing starts now ... *" -echo "* Good luck! *" -echo "***********************************************************************" -echo "VERSION: $VERSION" - -# Set to zero if not running on example hardware -grep ubi /proc/devices > /dev/null -if [ $? -ne "0" ]; then - echo "No UBI found in /proc/devices! I am broken!" - exit_failure -fi - -# Set to zero if not running on example hardware -grep 1142 /proc/cpuinfo > /dev/null -if [ $? -eq "0" ]; then - echo "Running on example hardware" - mount -o remount,rw / / - sleep 1 - fix_sysfs_issue -else - echo "Running on Artems hardware" -fi - -for volume in `seq $MINVOL $MAXVOL`; do - echo -n "************ VOLUME $volume NEW$volume " - echo "******************************************" - writevol_test $volume $SIZE_1M dynamic - jffs2_test NEW$volume $ITERATIONS - delete_volume $volume -done - -echo "***********************************************************************" -echo "* Congratulations, no errors found! *" -echo "* Have fun with your cool UBI system! *" -echo "***********************************************************************" - -exit_success diff --git a/ubi-utils/src/ubiupdatevol.c b/ubi-utils/src/ubiupdatevol.c deleted file mode 100644 index 807b961..0000000 --- a/ubi-utils/src/ubiupdatevol.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (c) International Business Machines Corp., 2006 - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * An utility to update UBI volumes. - * - * Author: Frank Haverkamp - * Joshua W. Boyer - * - * 1.0 Reworked the userinterface to use argp. - * 1.1 Removed argp parsing because we want to use uClib. - * 1.2 Minor cleanups - * 1.3 Use a different libubi - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define PROGRAM_VERSION "1.3" - -#define MAXPATH 1024 -#define BUFSIZE 128 * 1024 -#define MIN(x,y) ((x)<(y)?(x):(y)) - -struct args { - int devn; - int vol_id; - int truncate; - int broken_update; - int bufsize; - - /* special stuff needed to get additional arguments */ - char *arg1; - char **options; /* [STRING...] */ -}; - -static struct args myargs = { - .devn = -1, - .vol_id = -1, - .truncate = 0, - .broken_update = 0, - .bufsize = BUFSIZE, - .arg1 = NULL, - .options = NULL, -}; - -static int verbose = 0; - -static char doc[] = "\nVersion: " PROGRAM_VERSION "\n" - "ubiupdatevol - write to UBI Volume.\n"; - -static const char *optionsstr = -" -B, --broken-update broken update, this is for testing\n" -" -d, --devn= UBI device\n" -" -n, --vol_id= UBI volume id\n" -" -t, --truncate truncate volume\n" -" -?, --help Give this help list\n" -" --usage Give a short usage message\n" -" -V, --version Print program version\n"; - -static const char *usage = -"Usage: ubiupdatevol [-Bt?V] [-d ] [-n ] [--broken-update]\n" -" [--devn=] [--vol_id=] [--truncate] [--help]\n" -" [--usage] [--version] \n"; - -struct option long_options[] = { - { .name = "broken-update", .has_arg = 0, .flag = NULL, .val = 'B' }, - { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, - { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, - { .name = "truncate", .has_arg = 0, .flag = NULL, .val = 't' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = '?' }, - { .name = "usage", .has_arg = 0, .flag = NULL, .val = 0 }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0} -}; - -/* - * @brief Parse the arguments passed into the test case. - */ -static int -parse_opt(int argc, char **argv, struct args *args) -{ - while (1) { - int key; - - key = getopt_long(argc, argv, "Bd:n:t?V", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'v': /* --verbose= */ - verbose = strtoul(optarg, (char **)NULL, 0); - break; - - case 'n': /* --vol_id= */ - args->vol_id = strtol(optarg, (char **)NULL, 0); - break; - - case 'd': /* --devn= */ - args->devn = strtol(optarg, (char **)NULL, 0); - break; - - case 'b': /* --bufsize= */ - args->bufsize = strtol(optarg, (char **)NULL, 0); - if (args->bufsize <= 0) - args->bufsize = BUFSIZE; - break; - - case 't': /* --truncate */ - args->truncate = 1; - break; - - case 'B': /* --broken-update */ - args->broken_update = 1; - break; - - case '?': /* help */ - fprintf(stderr, "Usage: " - "ubiupdatevol [OPTION...] \n%s%s" - "\nReport bugs to %s\n", - doc, optionsstr, PACKAGE_BUGREPORT); - exit(EXIT_SUCCESS); - break; - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(0); - break; - - default: - fprintf(stderr, "%s", usage); - exit(EXIT_FAILURE); - } - } - - if (optind < argc) { - /* only one additional argument required */ - args->arg1 = argv[optind++]; - } - return 0; -} - -/** - * @bytes bytes must be always 0, if not 0 this is a testcase for a - * broken volume update where data is promissed to be written, but for - * some reason nothing is written. The volume is unusable after this. - */ -static int -ubi_truncate_volume(struct args *args, int64_t bytes,libubi_t libubi) -{ - int rc, ofd; - char path[MAXPATH]; - int old_errno; - - snprintf(path, MAXPATH-1, "/dev/ubi%d_%d", args->devn, args->vol_id); - path[MAXPATH-1] = '\0'; - - ofd = open(path, O_RDWR); - if (ofd < 0) { - fprintf(stderr, "Cannot open volume %s\n", path); - exit(EXIT_FAILURE); - } - rc = ubi_update_start(libubi, ofd, bytes); - old_errno = errno; - if (rc < 0) { - perror("UBI volume update ioctl"); - fprintf(stderr, " rc=%d errno=%d\n", rc, old_errno); - exit(EXIT_FAILURE); - } - close(ofd); - return 0; -} - -static ssize_t ubi_write(int fd, const void *buf, size_t count) -{ - int rc; - int len = count; - - while (len) { - rc = write(fd, buf, len); - if (rc == -1) { - if (errno == EINTR) - continue; /* try again */ - perror("write error"); - return rc; - } - - len -= rc; - buf += rc; - } - return count; -} - -static int -ubi_update_volume(struct args *args, libubi_t libubi) -{ - int rc, ofd; - FILE *ifp = NULL; - struct stat st; - int size = 0; - char *fname = args->arg1; - char path[MAXPATH]; - char *buf; - int64_t bytes = 0; - int old_errno; - - buf = malloc(args->bufsize); - if (!buf) { - perror("Out of memory"); - exit(EXIT_FAILURE); - } - - if (fname == NULL) { - fprintf(stderr, "Please specify an existing image file.\n"); - exit(EXIT_FAILURE); - } - - rc = stat(fname, &st); - if (rc < 0) { - fprintf(stderr, "Cannot stat input file %s\n", fname); - exit(EXIT_FAILURE); - } - bytes = size = st.st_size; - - ifp = fopen(fname, "r"); - if (!ifp) - exit(EXIT_FAILURE); - - snprintf(path, MAXPATH-1, "/dev/ubi%d_%d", args->devn, args->vol_id); - path[MAXPATH-1] = '\0'; - - ofd = open(path, O_RDWR); - if (ofd < 0) { - fprintf(stderr, "Cannot open UBI volume %s\n", path); - exit(EXIT_FAILURE); - } - - rc = ubi_update_start(libubi, ofd, bytes); - old_errno = errno; - if (rc < 0) { - perror("UBI volume update ioctl"); - fprintf(stderr, " rc=%d errno=%d\n", rc, old_errno); - exit(EXIT_FAILURE); - } - - while (size > 0) { - ssize_t tocopy = MIN(args->bufsize, size); - - rc = fread(buf, tocopy, 1, ifp); - if (rc != 1) { - perror("Could not read everything."); - exit(EXIT_FAILURE); - } - - rc = ubi_write(ofd, buf, tocopy); - old_errno = errno; - if (rc != tocopy) { - perror("Could not write to device"); - fprintf(stderr, " rc=%d errno=%d\n", rc, old_errno); - exit(EXIT_FAILURE); - } - size -= tocopy; - } - - free(buf); - fclose(ifp); - rc = close(ofd); - if (rc != 0) { - perror("UBI volume close failed"); - exit(EXIT_FAILURE); - } - return 0; -} - -int -main(int argc, char *argv[]) -{ - int rc; - libubi_t libubi; - - parse_opt(argc, argv, &myargs); - - libubi = libubi_open(); - if (libubi == NULL) { - perror("Cannot open libubi"); - return -1; - } - - if (myargs.truncate) { - rc = ubi_truncate_volume(&myargs, 0LL, libubi); - if (rc < 0) - goto out_libubi; - } - else if (myargs.broken_update) { - rc = ubi_truncate_volume(&myargs, 1LL, libubi); - if (rc < 0) - goto out_libubi; - } else { - rc = ubi_update_volume(&myargs, libubi); - if (rc < 0) - goto out_libubi; - } - - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} -- cgit v1.2.3