From patchwork Fri Apr 22 17:25:15 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artem Bityutskiy X-Patchwork-Id: 92559 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3C8ED1007DC for ; Sat, 23 Apr 2011 03:24:38 +1000 (EST) Received: from canuck.infradead.org ([2001:4978:20e::1]) by bombadil.infradead.org with esmtps (Exim 4.72 #1 (Red Hat Linux)) id 1QDK4L-00013W-0D; Fri, 22 Apr 2011 17:23:01 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.72 #1 (Red Hat Linux)) id 1QDK4I-0002tA-KI; Fri, 22 Apr 2011 17:22:58 +0000 Received: from smtp.nokia.com ([147.243.1.47] helo=mgw-sa01.nokia.com) by canuck.infradead.org with esmtps (Exim 4.72 #1 (Red Hat Linux)) id 1QDK3X-0002nh-1H for linux-mtd@lists.infradead.org; Fri, 22 Apr 2011 17:22:17 +0000 Received: from nokia.com (localhost [127.0.0.1]) by mgw-sa01.nokia.com (Switch-3.4.3/Switch-3.4.3) with ESMTP id p3MHM9Kr025968 for ; Fri, 22 Apr 2011 20:22:09 +0300 Received: from eru.research.nokia.com ([[172.21.24.121]]) by mgw-sa01.nokia.com with ESMTP id p3MHLiNv025326 ; Fri, 22 Apr 2011 20:21:47 +0300 From: Artem Bityutskiy To: MTD list Subject: [PATCH 04/13] fs-tests: integck: add -e option to verify operations Date: Fri, 22 Apr 2011 20:25:15 +0300 Message-Id: <1303493124-7619-5-git-send-email-dedekind1@gmail.com> X-Mailer: git-send-email 1.7.2.3 In-Reply-To: <1303493124-7619-1-git-send-email-dedekind1@gmail.com> References: <1303493124-7619-1-git-send-email-dedekind1@gmail.com> X-Nokia-AV: Clean X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110422_132211_469934_7AA3BF62 X-CRM114-Status: GOOD ( 16.96 ) X-Spam-Score: 3.4 (+++) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (3.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, low trust [147.243.1.47 listed in list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is freemail (dedekind1[at]gmail.com) 0.0 DKIM_ADSP_CUSTOM_MED No valid author signature, adsp_override is CUSTOM_MED 2.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit (dedekind1[at]gmail.com) 0.0 RFC_ABUSE_POST Both abuse and postmaster missing on sender domain 1.2 NML_ADSP_CUSTOM_MED ADSP custom_med hit, and not from a mailing list Cc: Adrian Hunter X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org From: Artem Bityutskiy Improve the test and add -e option which forces integck to verify all operation it performs. This patch does not implement file writes and holes operations so far - will be done in subsequent patches. Signed-off-by: Artem Bityutskiy --- tests/fs-tests/integrity/integck.c | 138 +++++++++++++++++++++++++++++++++--- 1 files changed, 127 insertions(+), 11 deletions(-) diff --git a/tests/fs-tests/integrity/integck.c b/tests/fs-tests/integrity/integck.c index 9822b3b..f39745f 100644 --- a/tests/fs-tests/integrity/integck.c +++ b/tests/fs-tests/integrity/integck.c @@ -68,6 +68,7 @@ static struct { long repeat_cnt; int power_cut_mode; + int verify_ops; int verbose; const char *mount_point; } args = { @@ -529,6 +530,13 @@ static int dir_new(struct dir_info *parent, const char *name) free(path); return -1; } + + if (args.verify_ops) { + struct stat st; + + CHECK(lstat(path, &st) == 0); + CHECK(S_ISDIR(st.st_mode)); + } free(path); add_dir_entry(parent, 'd', name, NULL); @@ -569,8 +577,16 @@ static int dir_remove(struct dir_info *dir) return -1; } + if (args.verify_ops) { + struct stat st; + + CHECK(lstat(path, &st) == -1); + CHECK(errno == ENOENT); + } + /* Remove entry from parent directory */ remove_dir_entry(dir->entry, 1); + free(path); return 0; } @@ -597,10 +613,17 @@ static int file_new(struct dir_info *parent, const char *name) free(path); return -1; } - free(path); + if (args.verify_ops) { + struct stat st; + + CHECK(lstat(path, &st) == 0); + CHECK(S_ISREG(st.st_mode)); + } file = add_dir_entry(parent, 'f', name, NULL); add_fd(file, fd); + + free(path); return 0; } @@ -610,6 +633,7 @@ static int link_new(struct dir_info *parent, const char *name, struct dir_entry_info *entry; char *path, *target; int ret; + struct stat st1, st2; entry = file->links; if (!entry) @@ -617,6 +641,10 @@ static int link_new(struct dir_info *parent, const char *name, path = dir_path(parent, name); target = dir_path(entry->parent, entry->name); + + if (args.verify_ops) + CHECK(lstat(target, &st1) == 0); + ret = link(target, path); if (ret != 0) { if (errno == ENOSPC) { @@ -629,9 +657,19 @@ static int link_new(struct dir_info *parent, const char *name, free(path); return ret; } + + if (args.verify_ops) { + CHECK(lstat(path, &st2) == 0); + CHECK(S_ISREG(st2.st_mode)); + CHECK(st1.st_ino == st2.st_ino); + CHECK(st2.st_nlink > 1); + CHECK(st2.st_nlink == st1.st_nlink + 1); + } + + add_dir_entry(parent, 'f', name, file); + free(target); free(path); - add_dir_entry(parent, 'f', name, file); return 0; } @@ -665,10 +703,18 @@ static int file_unlink(struct dir_entry_info *entry) free(path); return -1; } - free(path); + + if (args.verify_ops) { + struct stat st; + + CHECK(lstat(path, &st) == -1); + CHECK(errno == ENOENT); + } /* Remove file entry from parent directory */ remove_dir_entry(entry, 1); + + free(path); return 0; } @@ -984,6 +1030,9 @@ static int file_ftruncate(struct file_info *file, int fd, off_t new_length) return -1; } + if (args.verify_ops) + CHECK(lseek(fd, 0, SEEK_END) == new_length); + return 0; } @@ -1724,6 +1773,7 @@ static int rename_entry(struct dir_entry_info *entry) struct dir_info *parent; char *path, *to, *name; int ret, isdir, retry; + struct stat st1, st2; if (!entry->parent) return 0; @@ -1757,6 +1807,9 @@ static int rename_entry(struct dir_entry_info *entry) if (!path) return 0; + if (args.verify_ops) + CHECK(lstat(path, &st1) == 0); + ret = rename(path, to); if (ret != 0) { ret = 0; @@ -1772,6 +1825,11 @@ static int rename_entry(struct dir_entry_info *entry) return ret; } + if (args.verify_ops) { + CHECK(lstat(to, &st2) == 0); + CHECK(st1.st_ino == st2.st_ino); + } + free(path); free(to); @@ -1870,6 +1928,18 @@ static char *pick_symlink_target(const char *symlink_path) return rel_path; } +static void verify_symlink(const char *target, const char *path) +{ + int bytes; + char buf[PATH_MAX + 1]; + + bytes = readlink(path, buf, PATH_MAX); + CHECK(bytes >= 0); + CHECK(bytes < PATH_MAX); + buf[bytes] = '\0'; + CHECK(!strcmp(buf, target)); +} + static int symlink_new(struct dir_info *dir, const char *nm) { struct symlink_info *s; @@ -1896,10 +1966,14 @@ static int symlink_new(struct dir_info *dir, const char *nm) free(path); return ret; } - free(path); + + if (args.verify_ops) + verify_symlink(target, path); s = add_dir_entry(dir, 's', name, NULL); s->target_pathname = target; + + free(path); free(name); return 0; } @@ -1915,7 +1989,15 @@ static int symlink_remove(struct symlink_info *symlink) return -1; } + if (args.verify_ops) { + struct stat st; + + CHECK(lstat(path, &st) == -1); + CHECK(errno == ENOENT); + } + remove_dir_entry(symlink->entry, 1); + free(path); return 0; } @@ -2247,11 +2329,34 @@ static int rm_minus_rf_dir(const char *dir_name) CHECK(chdir(buf) == 0); CHECK(closedir(dir) == 0); + + if (args.verify_ops) { + dir = opendir(dir_name); + CHECK(dir != NULL); + do { + errno = 0; + dent = readdir(dir); + if (dent) + CHECK(!strcmp(dent->d_name, ".") || + !strcmp(dent->d_name, "..")); + } while (dent); + CHECK(errno == 0); + CHECK(closedir(dir) == 0); + } + ret = rmdir(dir_name); if (ret) { pcv("cannot remove directory %s", dir_name); return -1; } + + if (args.verify_ops) { + struct stat st; + + CHECK(lstat(dir_name, &st) == -1); + CHECK(errno == ENOENT); + } + return 0; } @@ -2600,6 +2705,11 @@ static const char doc[] = PROGRAM_NAME " version " PROGRAM_VERSION "directories, etc) should be there and the contents of the files should be\n" "correct. This is repeated a number of times (set with -n, default 1).\n" "\n" +"By default the test does not verify file-system modifications and assumes they\n" +"are done correctly if the file-system returns success. However, the -e flag\n" +"enables additional verifications and the test verifies all the file-system\n" +"operations it performs.\n" +"\n" "This test is also able to perform power cut testing. The underlying file-system\n" "or the device driver should be able to emulate power-cuts, by switching to R/O\n" "mode at random moments. And the file-system should return EROFS (read-only\n" @@ -2612,16 +2722,20 @@ static const char optionsstr[] = "-n, --repeat= repeat count, default is 1; zero value - repeat forever\n" "-p, --power-cut power cut testing mode (-n parameter is ignored and the\n" " test continues forever)\n" +"-e, --verify-ops verify all operations, e.g., every time a file is written\n" +" 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" "-h, -?, --help print help message\n" "-V, --version print program version\n"; 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 = "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' }, + { .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 = "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' }, { NULL, 0, NULL, 0}, }; @@ -2636,7 +2750,7 @@ static int parse_opts(int argc, char * const argv[]) while (1) { int key, error = 0; - key = getopt_long(argc, argv, "n:pvVh?", long_options, NULL); + key = getopt_long(argc, argv, "n:pevVh?", long_options, NULL); if (key == -1) break; @@ -2649,6 +2763,9 @@ static int parse_opts(int argc, char * const argv[]) case 'p': args.power_cut_mode = 1; break; + case 'e': + args.verify_ops = 1; + break; case 'v': args.verbose = 1; break; @@ -2867,7 +2984,6 @@ int main(int argc, char *argv[]) } while (ret); } - free_test_data(); out_free: