fs-tests: integck: implement MTD reattaching
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Fri, 20 May 2011 15:27:36 +0000 (18:27 +0300)
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>
Fri, 27 May 2011 12:55:06 +0000 (15:55 +0300)
This patch adds -m <mtdnum> option to integck and teaches integck to re-attach
the MTD device to UBI in case of an emulated power cut event. This is needed
for the new UBI power cut and unstable bits emulation infrastructure: when UBI
emulates a power cut the only way to recover form this is to re-attach the MTD
device.

Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
tests/fs-tests/integrity/Makefile
tests/fs-tests/integrity/integck.c

index 2cdd4702e0705cfb70c93e4c43ee0dfc76e932ab..509a94e6f69e9a3f9bc17f6a7487100eadaf17f1 100644 (file)
@@ -4,8 +4,11 @@ CC = gcc
 endif
 
 COMMON_HEADERS_DIR := ../../../include
+LIBUBI_PATH=../../../ubi-utils/
+LIBUBI_SRC_PATH=../../../ubi-utils/src/
+LIBUBI_HEADER_PATH=../../../ubi-utils/include
 
-CFLAGS := $(CFLAGS) -Wall -g -O2 -I$(COMMON_HEADERS_DIR)
+CFLAGS := $(CFLAGS) -Wall -g -O2 -I$(COMMON_HEADERS_DIR) -I$(LIBUBI_HEADER_PATH)
 
 LDFLAGS := $(LDFLAGS)
 
@@ -13,10 +16,17 @@ TARGETS = integck
 
 all: $(TARGETS)
 
+# Compile ubilib
+libubi.a:
+       $(CC) $(CFLAGS) -I $(LIBUBI_SRC_PATH) -c $(LIBUBI_SRC_PATH)/libubi.c -o libubi.o
+       ar cr libubi.a libubi.o
+
+$(TARGETS): libubi.a
+
 # Disable optimizations to make it possible to use gdb comfortably
 # Use -rdynamic to have stack backtraces
-debug:
-       gcc $(CFLAGS) -O0 -D INTEGCK_DEBUG -rdynamic integck.c -o integck
+debug: libubi.a
+       gcc $(CFLAGS) -O0 -D INTEGCK_DEBUG -rdynamic integck.c libubi.a -o integck
 
 clean:
-       rm -f *.o $(TARGETS)
+       rm -f *.o $(TARGETS) libubi.a
index c2bf964a4e2abd7b964698d8560d7ec8339be415..7fd662b01f7bc60c88d42e40bb6540ea3370505a 100644 (file)
@@ -40,6 +40,7 @@
 #define PROGRAM_VERSION "1.1"
 #define PROGRAM_NAME "integck"
 #include "common.h"
+#include "libubi.h"
 
 /*
  * WARNING! This is a dirty hack! The symbols for static functions are not
@@ -88,6 +89,8 @@ static struct {
        long repeat_cnt;
        int power_cut_mode;
        int verify_ops;
+       int reattach;
+       int mtdn;
        int verbose;
        const char *mount_point;
 } args = {
@@ -2937,6 +2940,8 @@ static const char optionsstr[] =
 "                     to, read the data back and verify it, every time a\n"
 "                     directory is created, check that it exists, etc\n"
 "-v, --verbose        be verbose about failures during power cut testing\n"
+"-m, --reattach=<mtd> re-attach mtd device number <mtd> (only if doing UBIFS power\n"
+"                     cut emulation testing)\n"
 "-h, -?, --help       print help message\n"
 "-V, --version        print program version\n";
 
@@ -2944,6 +2949,7 @@ static const struct option long_options[] = {
        { .name = "repeat",     .has_arg = 1, .flag = NULL, .val = 'n' },
        { .name = "power-cut",  .has_arg = 0, .flag = NULL, .val = 'p' },
        { .name = "verify-ops", .has_arg = 0, .flag = NULL, .val = 'e' },
+       { .name = "reattach",   .has_arg = 1, .flag = NULL, .val = 'm' },
        { .name = "verbose",    .has_arg = 0, .flag = NULL, .val = 'v' },
        { .name = "help",       .has_arg = 0, .flag = NULL, .val = 'h' },
        { .name = "version",    .has_arg = 0, .flag = NULL, .val = 'V' },
@@ -2961,7 +2967,7 @@ static int parse_opts(int argc, char * const argv[])
        while (1) {
                int key, error = 0;
 
-               key = getopt_long(argc, argv, "n:pevVh?", long_options, NULL);
+               key = getopt_long(argc, argv, "n:pm:evVh?", long_options, NULL);
                if (key == -1)
                        break;
 
@@ -2974,6 +2980,12 @@ static int parse_opts(int argc, char * const argv[])
                case 'p':
                        args.power_cut_mode = 1;
                        break;
+               case 'm':
+                       args.mtdn = simple_strtoul(optarg, &error);
+                       if (error || args.mtdn < 0)
+                               return errmsg("bad mtd device number: \"%s\"", optarg);
+                       args.reattach = 1;
+                       break;
                case 'e':
                        args.verify_ops = 1;
                        break;
@@ -3003,6 +3015,9 @@ static int parse_opts(int argc, char * const argv[])
        else if (optind != argc - 1)
                return errmsg("more then one test file-system specified (use -h for help)");
 
+       if (args.reattach && !args.power_cut_mode)
+               return errmsg("-m makes sense only together with -e");
+
        if (args.power_cut_mode)
                /* Repeat forever if we are in power cut testing mode */
                args.repeat_cnt = 0;
@@ -3041,7 +3056,47 @@ static void free_fs_info(struct dir_info *dir)
                        assert(0);
        }
 }
-/**
+
+/*
+ * Detach the MTD device from UBI and attach it back. This function is used
+ * whed performing emulated power cut testing andthe power cuts are amulated by
+ * UBI, not by UBIFS. In this case, to recover from the emulated power cut we
+ * have to unmount UBIFS and re-attach the MTD device.
+ */
+static int reattach(void)
+{
+       int err = 0;
+       libubi_t libubi;
+       struct ubi_attach_request req;
+
+       libubi = libubi_open();
+       if (!libubi) {
+               if (errno == 0)
+                       return errmsg("UBI is not present in the system");
+               return sys_errmsg("cannot open libubi");
+       }
+
+       err = ubi_detach_mtd(libubi, "/dev/ubi_ctrl", args.mtdn);
+       if (err) {
+               sys_errmsg("cannot detach mtd%d", args.mtdn);
+               goto out;
+       }
+
+       req.dev_num = UBI_DEV_NUM_AUTO;
+       req.mtd_num = args.mtdn;
+       req.vid_hdr_offset = 0;
+       req.mtd_dev_node = NULL;
+
+       err = ubi_attach(libubi, "/dev/ubi_ctrl", &req);
+       if (err)
+               sys_errmsg("cannot attach mtd%d", args.mtdn);
+
+out:
+       libubi_close(libubi);
+       return err;
+}
+
+/*
  * Recover the tested file-system from an emulated power cut failure by
  * unmounting it and mounting it again.
  */
@@ -3067,6 +3122,9 @@ static int recover_tested_fs(void)
        if (mntent)
                CHECK(umount(fsinfo.mount_point) != -1);
 
+       if (args.reattach)
+               CHECK(reattach() == 0);
+
        if (!um_rorw) {
                ret = mount(fsinfo.fsdev, fsinfo.mount_point,
                            fsinfo.fstype, fsinfo.mount_flags,