* [PATCH v4 0/2] xfstest btrfs/316: test send / receive
@ 2013-08-13 17:24 ` Jan Schmidt
0 siblings, 0 replies; 10+ messages in thread
From: Jan Schmidt @ 2013-08-13 17:24 UTC (permalink / raw)
To: xfs; +Cc: linux-btrfs, sbehrens, sandeen
These two patches add the announced tests for btrfs send / receive. As
requested, the fssum tool is now included.
--
v1->v2:
- included fssum
- test number is now 316 (was 314)
v2->v3:
- added missing -lcrypto to build fssum
- removed obsolete change in README now that fssum is included
- fixed comment in test/btrfs/316's header (314 -> 316)
v3->v4:
- build fssum with help of autotools only if libssl is available
- removed clumsy OPT_TARGETS in src/Makefile
- added #define directives for SEEK_DATA and SEEK_HOLE to fssum.c
Jan Schmidt (2):
xfstests: add fssum tool
xfstests btrfs/316: test send / receive
.gitignore | 1 +
aclocal.m4 | 1 +
configure.ac | 1 +
include/builddefs.in | 1 +
m4/Makefile | 1 +
m4/package_ssldev.m4 | 4 +
src/Makefile | 8 +
src/fssum.c | 828 ++++++++++++++++++++++++++++++++++++++++++++++++++
tests/btrfs/316 | 116 +++++++
tests/btrfs/316.out | 4 +
tests/btrfs/group | 1 +
11 files changed, 966 insertions(+), 0 deletions(-)
create mode 100644 m4/package_ssldev.m4
create mode 100644 src/fssum.c
create mode 100755 tests/btrfs/316
create mode 100644 tests/btrfs/316.out
--
1.7.2.5
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 0/2] xfstest btrfs/316: test send / receive
@ 2013-08-13 17:24 ` Jan Schmidt
0 siblings, 0 replies; 10+ messages in thread
From: Jan Schmidt @ 2013-08-13 17:24 UTC (permalink / raw)
To: xfs; +Cc: sandeen, sbehrens, linux-btrfs
These two patches add the announced tests for btrfs send / receive. As
requested, the fssum tool is now included.
--
v1->v2:
- included fssum
- test number is now 316 (was 314)
v2->v3:
- added missing -lcrypto to build fssum
- removed obsolete change in README now that fssum is included
- fixed comment in test/btrfs/316's header (314 -> 316)
v3->v4:
- build fssum with help of autotools only if libssl is available
- removed clumsy OPT_TARGETS in src/Makefile
- added #define directives for SEEK_DATA and SEEK_HOLE to fssum.c
Jan Schmidt (2):
xfstests: add fssum tool
xfstests btrfs/316: test send / receive
.gitignore | 1 +
aclocal.m4 | 1 +
configure.ac | 1 +
include/builddefs.in | 1 +
m4/Makefile | 1 +
m4/package_ssldev.m4 | 4 +
src/Makefile | 8 +
src/fssum.c | 828 ++++++++++++++++++++++++++++++++++++++++++++++++++
tests/btrfs/316 | 116 +++++++
tests/btrfs/316.out | 4 +
tests/btrfs/group | 1 +
11 files changed, 966 insertions(+), 0 deletions(-)
create mode 100644 m4/package_ssldev.m4
create mode 100644 src/fssum.c
create mode 100755 tests/btrfs/316
create mode 100644 tests/btrfs/316.out
--
1.7.2.5
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 1/2] xfstests: add fssum tool
2013-08-13 17:24 ` Jan Schmidt
@ 2013-08-13 17:24 ` Jan Schmidt
-1 siblings, 0 replies; 10+ messages in thread
From: Jan Schmidt @ 2013-08-13 17:24 UTC (permalink / raw)
To: xfs; +Cc: linux-btrfs, sbehrens, sandeen
fssum is a tool to build a recursive checksum for a file system. The home
repository of fssum is
git://git.kernel.org/pub/scm/linux/kernel/git/arne/far-progs.git
Signed-off-by: Jan Schmidt <list.xfs@jan-o-sch.net>
---
.gitignore | 1 +
aclocal.m4 | 1 +
configure.ac | 1 +
include/builddefs.in | 1 +
m4/Makefile | 1 +
m4/package_ssldev.m4 | 4 +
src/Makefile | 8 +
src/fssum.c | 828 ++++++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 845 insertions(+), 0 deletions(-)
create mode 100644 m4/package_ssldev.m4
create mode 100644 src/fssum.c
diff --git a/.gitignore b/.gitignore
index 11594aa..c2fc6e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,6 +45,7 @@
/src/fill
/src/fill2
/src/fs_perms
+/src/fssum
/src/fstest
/src/fsync-tester
/src/ftrunc
diff --git a/aclocal.m4 b/aclocal.m4
index 5739004..f3412e1 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -44,6 +44,7 @@ m4_include([m4/package_attrdev.m4])
m4_include([m4/package_dmapidev.m4])
m4_include([m4/package_gdbmdev.m4])
m4_include([m4/package_globals.m4])
+m4_include([m4/package_ssldev.m4])
m4_include([m4/package_utilies.m4])
m4_include([m4/package_uuiddev.m4])
m4_include([m4/package_xfslibs.m4])
diff --git a/configure.ac b/configure.ac
index bfae106..bd48fd9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,6 +70,7 @@ in
AC_PACKAGE_WANT_FALLOCATE
AC_PACKAGE_WANT_LINUX_PRCTL_H
AC_PACKAGE_WANT_LINUX_FS_H
+ AC_PACKAGE_WANT_SSL
;;
esac
diff --git a/include/builddefs.in b/include/builddefs.in
index 6519c13..24f838f 100644
--- a/include/builddefs.in
+++ b/include/builddefs.in
@@ -61,6 +61,7 @@ ENABLE_SHARED = @enable_shared@
HAVE_DB = @have_db@
HAVE_AIO = @have_aio@
HAVE_FALLOCATE = @have_fallocate@
+HAVE_SSL = @have_ssl@
HAVE_DMAPI = @have_dmapi@
HAVE_ATTR_LIST = @have_attr_list@
HAVE_FIEMAP = @have_fiemap@
diff --git a/m4/Makefile b/m4/Makefile
index 6c1d0e4..7fbff82 100644
--- a/m4/Makefile
+++ b/m4/Makefile
@@ -16,6 +16,7 @@ LSRCFILES = \
package_libcdev.m4 \
package_ncurses.m4 \
package_pthread.m4 \
+ package_ssldev.m4 \
package_types.m4 \
package_utilies.m4 \
package_uuiddev.m4 \
diff --git a/m4/package_ssldev.m4 b/m4/package_ssldev.m4
new file mode 100644
index 0000000..2eae3c5
--- /dev/null
+++ b/m4/package_ssldev.m4
@@ -0,0 +1,4 @@
+AC_DEFUN([AC_PACKAGE_WANT_SSL],
+ [ AC_CHECK_HEADERS(openssl/md5.h, [ have_ssl=true ], [ have_ssl=false ])
+ AC_SUBST(have_ssl)
+ ])
diff --git a/src/Makefile b/src/Makefile
index cc679e8..b2dfdcb 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -56,6 +56,14 @@ ifeq ($(HAVE_AIO), true)
SUBDIRS += aio-dio-regress
endif
+ifeq ($(HAVE_SSL), true)
+TARGETS += fssum
+LLDLIBS += -lssl -lcrypto
+ifeq ($(PKG_PLATFORM),linux)
+CFLAGS += -D__LINUX__
+endif
+endif
+
CFILES = $(TARGETS:=.c)
LDIRT = $(TARGETS)
diff --git a/src/fssum.c b/src/fssum.c
new file mode 100644
index 0000000..c75ff8b
--- /dev/null
+++ b/src/fssum.c
@@ -0,0 +1,828 @@
+/*
+ * Copyright (C) 2012 STRATO AG. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+#ifdef __LINUX__
+#define _BSD_SOURCE
+#define _LARGEFILE64_SOURCE
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef __SOLARIS__
+#include <sys/mkdev.h>
+#endif
+#include <openssl/md5.h>
+#include <netinet/in.h>
+#include <inttypes.h>
+#include <assert.h>
+
+#define CS_SIZE 16
+#define CHUNKS 128
+
+#ifdef __LINUX__
+#ifndef SEEK_DATA
+#define SEEK_DATA 3
+#define SEEK_HOLE 4
+#endif
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define htonll(x) __bswap_64 (x)
+#endif
+#endif
+
+/* TODO: add hardlink recognition */
+/* TODO: add xattr/acl */
+
+struct excludes {
+ char *path;
+ int len;
+};
+
+typedef struct _sum {
+ MD5_CTX md5;
+ unsigned char out[16];
+} sum_t;
+
+typedef int (*sum_file_data_t)(int fd, sum_t *dst);
+
+int gen_manifest = 0;
+int in_manifest = 0;
+char *checksum = NULL;
+struct excludes *excludes;
+int n_excludes = 0;
+int verbose = 0;
+FILE *out_fp;
+FILE *in_fp;
+
+enum _flags {
+ FLAG_UID,
+ FLAG_GID,
+ FLAG_MODE,
+ FLAG_ATIME,
+ FLAG_MTIME,
+ FLAG_CTIME,
+ FLAG_DATA,
+ FLAG_OPEN_ERROR,
+ FLAG_STRUCTURE,
+ NUM_FLAGS
+};
+
+const char flchar[] = "ugoamcdes";
+char line[65536];
+
+int flags[NUM_FLAGS] = {1, 1, 1, 1, 1, 0, 1, 0, 0};
+
+char *
+getln(char *buf, int size, FILE *fp)
+{
+ char *p;
+ int l;
+
+ p = fgets(buf, size, fp);
+ if (!p)
+ return NULL;
+
+ l = strlen(p);
+ while(l > 0 && (p[l - 1] == '\n' || p[l - 1] == '\r'))
+ p[--l] = 0;
+
+ return p;
+}
+
+void
+parse_flag(int c)
+{
+ int i;
+ int is_upper = 0;
+
+ if (c >= 'A' && c <= 'Z') {
+ is_upper = 1;
+ c += 'a' - 'A';
+ }
+ for (i = 0; flchar[i]; ++i) {
+ if (flchar[i] == c) {
+ flags[i] = is_upper ? 0 : 1;
+ return;
+ }
+ }
+ fprintf(stderr, "unrecognized flag %c\n", c);
+ exit(-1);
+}
+
+void
+parse_flags(char *p)
+{
+ while (*p)
+ parse_flag(*p++);
+}
+
+void
+usage(void)
+{
+ fprintf(stderr, "usage: fssum <options> <path>\n");
+ fprintf(stderr, " options:\n");
+ fprintf(stderr, " -f : write out a full manifest file\n");
+ fprintf(stderr, " -w <file> : send output to file\n");
+ fprintf(stderr, " -v : verbose mode (debugging only)\n");
+ fprintf(stderr,
+ " -r <file> : read checksum or manifest from file\n");
+ fprintf(stderr, " -[ugoamcde] : specify which fields to include in checksum calculation.\n");
+ fprintf(stderr, " u : include uid\n");
+ fprintf(stderr, " g : include gid\n");
+ fprintf(stderr, " o : include mode\n");
+ fprintf(stderr, " m : include mtime\n");
+ fprintf(stderr, " a : include atime\n");
+ fprintf(stderr, " c : include ctime\n");
+ fprintf(stderr, " d : include file data\n");
+ fprintf(stderr, " e : include open errors (aborts otherwise)\n");
+ fprintf(stderr, " s : include block structure (holes)\n");
+ fprintf(stderr, " -[UGOAMCDES]: exclude respective field from calculation\n");
+ fprintf(stderr, " -n : reset all flags\n");
+ fprintf(stderr, " -N : set all flags\n");
+ fprintf(stderr, " -x path : exclude path when building checksum (multiple ok)\n");
+ fprintf(stderr, " -h : this help\n\n");
+ fprintf(stderr, "The default field mask is ugoamCdES. If the checksum/manifest is read from a\n");
+ fprintf(stderr, "file, the mask is taken from there and the values given on the command line\n");
+ fprintf(stderr, "are ignored.\n");
+ exit(-1);
+}
+
+static char buf[65536];
+
+void *
+alloc(size_t sz)
+{
+ void *p = malloc(sz);
+
+ if (!p) {
+ fprintf(stderr, "malloc failed\n");
+ exit(-1);
+ }
+
+ return p;
+}
+
+void
+sum_init(sum_t *cs)
+{
+ MD5_Init(&cs->md5);
+}
+
+void
+sum_fini(sum_t *cs)
+{
+ MD5_Final(cs->out, &cs->md5);
+}
+
+void
+sum_add(sum_t *cs, void *buf, int size)
+{
+ MD5_Update(&cs->md5, buf, size);
+}
+
+void
+sum_add_sum(sum_t *dst, sum_t *src)
+{
+ sum_add(dst, src->out, sizeof(src->out));
+}
+
+void
+sum_add_u64(sum_t *dst, uint64_t val)
+{
+ uint64_t v = htonll(val);
+ sum_add(dst, &v, sizeof(v));
+}
+
+void
+sum_add_time(sum_t *dst, time_t t)
+{
+ sum_add_u64(dst, t);
+}
+
+char *
+sum_to_string(sum_t *dst)
+{
+ int i;
+ char *s = alloc(CS_SIZE * 2 + 1);
+
+ for (i = 0; i < CS_SIZE; ++i)
+ sprintf(s + i * 2, "%02x", dst->out[i]);
+
+ return s;
+}
+
+int
+sum_file_data_permissive(int fd, sum_t *dst)
+{
+ int ret;
+ off_t pos;
+ off_t old;
+ int i;
+ uint64_t zeros = 0;
+
+ pos = lseek(fd, 0, SEEK_CUR);
+ if (pos == (off_t)-1)
+ return errno == ENXIO ? 0 : -2;
+
+ while (1) {
+ old = pos;
+ pos = lseek(fd, pos, SEEK_DATA);
+ if (pos == (off_t)-1) {
+ if (errno == ENXIO) {
+ ret = 0;
+ pos = lseek(fd, 0, SEEK_END);
+ if (pos != (off_t)-1)
+ zeros += pos - old;
+ } else {
+ ret = -2;
+ }
+ break;
+ }
+ ret = read(fd, buf, sizeof(buf));
+ assert(ret); /* eof found by lseek */
+ if (ret <= 0)
+ break;
+ if (old < pos) /* hole */
+ zeros += pos - old;
+ for (i = 0; i < ret; ++i) {
+ for (old = i; buf[i] == 0 && i < ret; ++i)
+ ;
+ if (old < i) /* code like a hole */
+ zeros += i - old;
+ if (i == ret)
+ break;
+ if (zeros) {
+ if (verbose >= 2)
+ fprintf(stderr,
+ "adding %llu zeros to sum\n",
+ (unsigned long long)zeros);
+ sum_add_u64(dst, 0);
+ sum_add_u64(dst, zeros);
+ zeros = 0;
+ }
+ for (old = i; buf[i] != 0 && i < ret; ++i)
+ ;
+ if (verbose >= 2)
+ fprintf(stderr, "adding %u non-zeros to sum\n",
+ i - (int)old);
+ sum_add(dst, buf + old, i - old);
+ }
+ pos += ret;
+ }
+
+ if (zeros) {
+ if (verbose >= 2)
+ fprintf(stderr,
+ "adding %llu zeros to sum (finishing)\n",
+ (unsigned long long)zeros);
+ sum_add_u64(dst, 0);
+ sum_add_u64(dst, zeros);
+ }
+
+ return ret;
+}
+
+int
+sum_file_data_strict(int fd, sum_t *dst)
+{
+ int ret;
+ off_t pos;
+
+ pos = lseek(fd, 0, SEEK_CUR);
+ if (pos == (off_t)-1)
+ return errno == ENXIO ? 0 : -2;
+
+ while (1) {
+ pos = lseek(fd, pos, SEEK_DATA);
+ if (pos == (off_t)-1)
+ return errno == ENXIO ? 0 : -2;
+ ret = read(fd, buf, sizeof(buf));
+ assert(ret); /* eof found by lseek */
+ if (ret <= 0)
+ return ret;
+ if (verbose >= 2)
+ fprintf(stderr,
+ "adding to sum at file offset %llu, %d bytes\n",
+ (unsigned long long)pos, ret);
+ sum_add_u64(dst, (uint64_t)pos);
+ sum_add(dst, buf, ret);
+ pos += ret;
+ }
+}
+
+char *
+escape(char *in)
+{
+ char *out = alloc(strlen(in) * 3 + 1);
+ char *src = in;
+ char *dst = out;
+
+ for (; *src; ++src) {
+ if (*src >= 32 && *src < 127 && *src != '\\') {
+ *dst++ = *src;
+ } else {
+ sprintf(dst, "\\%02x", (unsigned char)*src);
+ dst += 3;
+ }
+ }
+ *dst = 0;
+
+ return out;
+}
+
+void
+excess_file(const char *fn)
+{
+ printf("only in local fs: %s\n", fn);
+}
+
+void
+missing_file(const char *fn)
+{
+ printf("only in remote fs: %s\n", fn);
+}
+
+int
+pathcmp(const char *a, const char *b)
+{
+ int len_a = strlen(a);
+ int len_b = strlen(b);
+
+ /*
+ * as the containing directory is sent after the files, it has to
+ * come out bigger in the comparison.
+ */
+ if (len_a < len_b && a[len_a - 1] == '/' && strncmp(a, b, len_a) == 0)
+ return 1;
+ if (len_a > len_b && b[len_b - 1] == '/' && strncmp(a, b, len_b) == 0)
+ return -1;
+
+ return strcmp(a, b);
+}
+
+void
+check_match(char *fn, char *local_m, char *remote_m,
+ char *local_c, char *remote_c)
+{
+ int match_m = !strcmp(local_m, remote_m);
+ int match_c = !strcmp(local_c, remote_c);
+
+ if (match_m && !match_c) {
+ printf("data mismatch in %s\n", fn);
+ } else if (!match_m && match_c) {
+ printf("metadata mismatch in %s\n", fn);
+ } else if (!match_m && !match_c) {
+ printf("metadata and data mismatch in %s\n", fn);
+ }
+}
+
+char *prev_fn;
+char *prev_m;
+char *prev_c;
+void
+check_manifest(char *fn, char *m, char *c, int last_call)
+{
+ char *rem_m;
+ char *rem_c;
+ char *l;
+ int cmp;
+
+ if (prev_fn) {
+ if (last_call)
+ cmp = -1;
+ else
+ cmp = pathcmp(prev_fn, fn);
+ if (cmp > 0) {
+ excess_file(fn);
+ return;
+ } else if (cmp < 0) {
+ missing_file(prev_fn);
+ } else {
+ check_match(fn, m, prev_m, c, prev_c);
+ }
+ free(prev_fn);
+ free(prev_m);
+ free(prev_c);
+ prev_fn = NULL;
+ prev_m = NULL;
+ prev_c = NULL;
+ if (cmp == 0)
+ return;
+ }
+ while ((l = getln(line, sizeof(line), in_fp))) {
+ rem_c = strrchr(l, ' ');
+ if (!rem_c) {
+ /* final cs */
+ checksum = strdup(l);
+ break;
+ }
+ if (rem_c == l) {
+malformed:
+ fprintf(stderr, "malformed input\n");
+ exit(-1);
+ }
+ *rem_c++ = 0;
+ rem_m = strrchr(l, ' ');
+ if (!rem_m)
+ goto malformed;
+ *rem_m++ = 0;
+
+ if (last_call)
+ cmp = -1;
+ else
+ cmp = pathcmp(l, fn);
+ if (cmp == 0) {
+ check_match(fn, m, rem_m, c, rem_c);
+ return;
+ } else if (cmp > 0) {
+ excess_file(fn);
+ prev_fn = strdup(l);
+ prev_m = strdup(rem_m);
+ prev_c = strdup(rem_c);
+ return;
+ }
+ missing_file(l);
+ }
+ if (!last_call)
+ excess_file(fn);
+}
+
+int
+namecmp(const void *aa, const void *bb)
+{
+ char * const *a = aa;
+ char * const *b = bb;
+
+ return strcmp(*a, *b);
+}
+
+void
+sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
+{
+ DIR *d;
+ struct dirent *de;
+ char **namelist = NULL;
+ int alloclen = 0;
+ int entries = 0;
+ int i;
+ int ret;
+ int fd;
+ int excl;
+ sum_file_data_t sum_file_data = flags[FLAG_STRUCTURE] ?
+ sum_file_data_strict : sum_file_data_permissive;
+
+ d = fdopendir(dirfd);
+ if (!d) {
+ perror("opendir");
+ exit(-1);
+ }
+ while((de = readdir(d))) {
+ if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
+ continue;
+ if (entries == alloclen) {
+ alloclen += CHUNKS;
+ namelist = realloc(namelist,
+ alloclen * sizeof(*namelist));
+ if (!namelist) {
+ fprintf(stderr, "malloc failed\n");
+ exit(-1);
+ }
+ }
+ namelist[entries] = strdup(de->d_name);
+ if (!namelist[entries]) {
+ fprintf(stderr, "malloc failed\n");
+ exit(-1);
+ }
+ ++entries;
+ }
+ qsort(namelist, entries, sizeof(*namelist), namecmp);
+ for (i = 0; i < entries; ++i) {
+ struct stat64 st;
+ sum_t cs;
+ sum_t meta;
+ char *path;
+
+ sum_init(&cs);
+ sum_init(&meta);
+ path = alloc(strlen(path_in) + strlen(namelist[i]) + 3);
+ sprintf(path, "%s/%s", path_in, namelist[i]);
+ for (excl = 0; excl < n_excludes; ++excl) {
+ if (strncmp(excludes[excl].path, path,
+ excludes[excl].len) == 0)
+ goto next;
+ }
+
+ ret = fchdir(dirfd);
+ if (ret == -1) {
+ perror("fchdir");
+ exit(-1);
+ }
+ ret = lstat64(namelist[i], &st);
+ if (ret) {
+ fprintf(stderr, "stat failed for %s/%s: %s\n",
+ path_prefix, path, strerror(errno));
+ exit(-1);
+ }
+ sum_add_u64(&meta, level);
+ sum_add(&meta, namelist[i], strlen(namelist[i]));
+ if (!S_ISDIR(st.st_mode))
+ sum_add_u64(&meta, st.st_nlink);
+ if (flags[FLAG_UID])
+ sum_add_u64(&meta, st.st_uid);
+ if (flags[FLAG_GID])
+ sum_add_u64(&meta, st.st_gid);
+ if (flags[FLAG_MODE])
+ sum_add_u64(&meta, st.st_mode);
+ if (flags[FLAG_ATIME])
+ sum_add_time(&meta, st.st_atime);
+ if (flags[FLAG_MTIME])
+ sum_add_time(&meta, st.st_mtime);
+ if (flags[FLAG_CTIME])
+ sum_add_time(&meta, st.st_ctime);
+ if (S_ISDIR(st.st_mode)) {
+ fd = openat(dirfd, namelist[i], 0);
+ if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
+ sum_add_u64(&meta, errno);
+ } else if (fd == -1) {
+ fprintf(stderr, "open failed for %s/%s: %s\n",
+ path_prefix, path, strerror(errno));
+ exit(-1);
+ } else {
+ sum(fd, level + 1, &cs, path_prefix, path);
+ close(fd);
+ }
+ } else if (S_ISREG(st.st_mode)) {
+ sum_add_u64(&meta, st.st_size);
+ if (flags[FLAG_DATA]) {
+ if (verbose)
+ fprintf(stderr, "file %s\n",
+ namelist[i]);
+ fd = openat(dirfd, namelist[i], 0);
+ if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
+ sum_add_u64(&meta, errno);
+ } else if (fd == -1) {
+ fprintf(stderr,
+ "open failed for %s/%s: %s\n",
+ path_prefix, path,
+ strerror(errno));
+ exit(-1);
+ }
+ if (fd != -1) {
+ ret = sum_file_data(fd, &cs);
+ if (ret < 0) {
+ fprintf(stderr,
+ "read failed for "
+ "%s/%s: %s\n",
+ path_prefix, path,
+ strerror(errno));
+ exit(-1);
+ }
+ close(fd);
+ }
+ }
+ } else if (S_ISLNK(st.st_mode)) {
+ ret = readlink(namelist[i], buf, sizeof(buf));
+ if (ret == -1) {
+ perror("readlink");
+ exit(-1);
+ }
+ sum_add(&cs, buf, ret);
+ } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
+ sum_add_u64(&cs, major(st.st_rdev));
+ sum_add_u64(&cs, minor(st.st_rdev));
+ }
+ sum_fini(&cs);
+ sum_fini(&meta);
+ if (gen_manifest || in_manifest) {
+ char *fn;
+ char *m;
+ char *c;
+
+ if (S_ISDIR(st.st_mode))
+ strcat(path, "/");
+ fn = escape(path);
+ m = sum_to_string(&meta);
+ c = sum_to_string(&cs);
+
+ if (gen_manifest)
+ fprintf(out_fp, "%s %s %s\n", fn, m, c);
+ if (in_manifest)
+ check_manifest(fn, m, c, 0);
+ free(c);
+ free(m);
+ free(fn);
+ }
+ sum_add_sum(dircs, &cs);
+ sum_add_sum(dircs, &meta);
+next:
+ free(path);
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ extern char *optarg;
+ extern int optind;
+ int c;
+ char *path;
+ int fd;
+ sum_t cs;
+ char flagstring[sizeof(flchar)];
+ int i;
+ int plen;
+ int elen;
+ int n_flags = 0;
+ const char *allopts = "heEfuUgGoOaAmMcCdDsSnNw:r:vx:";
+
+ out_fp = stdout;
+ while ((c = getopt(argc, argv, allopts)) != EOF) {
+ switch(c) {
+ case 'f':
+ gen_manifest = 1;
+ break;
+ case 'u':
+ case 'U':
+ case 'g':
+ case 'G':
+ case 'o':
+ case 'O':
+ case 'a':
+ case 'A':
+ case 'm':
+ case 'M':
+ case 'c':
+ case 'C':
+ case 'd':
+ case 'D':
+ case 'e':
+ case 'E':
+ case 's':
+ case 'S':
+ ++n_flags;
+ parse_flag(c);
+ break;
+ case 'n':
+ for (i = 0; i < NUM_FLAGS; ++i)
+ flags[i] = 0;
+ break;
+ case 'N':
+ for (i = 0; i < NUM_FLAGS; ++i)
+ flags[i] = 1;
+ break;
+ case 'w':
+ out_fp = fopen(optarg, "w");
+ if (!out_fp) {
+ fprintf(stderr,
+ "failed to open output file: %s\n",
+ strerror(errno));
+ exit(-1);
+ }
+ break;
+ case 'r':
+ in_fp = fopen(optarg, "r");
+ if (!in_fp) {
+ fprintf(stderr,
+ "failed to open input file: %s\n",
+ strerror(errno));
+ exit(-1);
+ }
+ break;
+ case 'x':
+ ++n_excludes;
+ excludes = realloc(excludes,
+ sizeof(*excludes) * n_excludes);
+ if (!excludes) {
+ fprintf(stderr,
+ "failed to alloc exclude space\n");
+ exit(-1);
+ }
+ excludes[n_excludes - 1].path = optarg;
+ break;
+ case 'v':
+ ++verbose;
+ break;
+ case 'h':
+ case '?':
+ usage();
+ }
+ }
+
+ if (optind + 1 != argc) {
+ fprintf(stderr, "missing path\n");
+ usage();
+ }
+
+ if (in_fp) {
+ char *l = getln(line, sizeof(line), in_fp);
+ char *p;
+
+ if (l == NULL) {
+ fprintf(stderr, "failed to read line from input\n");
+ exit(-1);
+ }
+ if (strncmp(l, "Flags: ", 7) == 0) {
+ l += 7;
+ in_manifest = 1;
+ parse_flags(l);
+ } else if ((p = strchr(l, ':'))) {
+ *p++ = 0;
+ parse_flags(l);
+ checksum = strdup(p);
+ } else {
+ fprintf(stderr, "invalid input file format\n");
+ exit(-1);
+ }
+ if (n_flags)
+ fprintf(stderr, "warning: "
+ "command line flags ignored in -r mode\n");
+ }
+ strcpy(flagstring, flchar);
+ for (i = 0; i < NUM_FLAGS; ++i) {
+ if (flags[i] == 0)
+ flagstring[i] -= 'a' - 'A';
+ }
+
+ path = argv[optind];
+ plen = strlen(path);
+ if (path[plen - 1] == '/') {
+ --plen;
+ path[plen] = '\0';
+ }
+
+ for (i = 0; i < n_excludes; ++i) {
+ if (strncmp(path, excludes[i].path, plen) != 0)
+ fprintf(stderr,
+ "warning: exclude %s outside of path %s\n",
+ excludes[i].path, path);
+ else
+ excludes[i].path += plen;
+ elen = strlen(excludes[i].path);
+ if (excludes[i].path[elen - 1] == '/')
+ --elen;
+ excludes[i].path[elen] = '\0';
+ excludes[i].len = elen;
+ }
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1) {
+ fprintf(stderr, "failed to open %s: %s\n", path,
+ strerror(errno));
+ exit(-1);
+ }
+
+ if (gen_manifest)
+ fprintf(out_fp, "Flags: %s\n", flagstring);
+
+ sum_init(&cs);
+ sum(fd, 1, &cs, path, "");
+ sum_fini(&cs);
+
+ close(fd);
+ if (in_manifest)
+ check_manifest("", "", "", 1);
+
+ if (!checksum) {
+ if (in_manifest) {
+ fprintf(stderr, "malformed input\n");
+ exit(-1);
+ }
+ if (!gen_manifest)
+ fprintf(out_fp, "%s:", flagstring);
+
+ fprintf(out_fp, "%s\n", sum_to_string(&cs));
+ } else {
+ if (strcmp(checksum, sum_to_string(&cs)) == 0) {
+ printf("OK\n");
+ exit(0);
+ } else {
+ printf("FAIL\n");
+ exit(1);
+ }
+ }
+
+ exit(0);
+}
--
1.7.2.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 1/2] xfstests: add fssum tool
@ 2013-08-13 17:24 ` Jan Schmidt
0 siblings, 0 replies; 10+ messages in thread
From: Jan Schmidt @ 2013-08-13 17:24 UTC (permalink / raw)
To: xfs; +Cc: sandeen, sbehrens, linux-btrfs
fssum is a tool to build a recursive checksum for a file system. The home
repository of fssum is
git://git.kernel.org/pub/scm/linux/kernel/git/arne/far-progs.git
Signed-off-by: Jan Schmidt <list.xfs@jan-o-sch.net>
---
.gitignore | 1 +
aclocal.m4 | 1 +
configure.ac | 1 +
include/builddefs.in | 1 +
m4/Makefile | 1 +
m4/package_ssldev.m4 | 4 +
src/Makefile | 8 +
src/fssum.c | 828 ++++++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 845 insertions(+), 0 deletions(-)
create mode 100644 m4/package_ssldev.m4
create mode 100644 src/fssum.c
diff --git a/.gitignore b/.gitignore
index 11594aa..c2fc6e3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,6 +45,7 @@
/src/fill
/src/fill2
/src/fs_perms
+/src/fssum
/src/fstest
/src/fsync-tester
/src/ftrunc
diff --git a/aclocal.m4 b/aclocal.m4
index 5739004..f3412e1 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -44,6 +44,7 @@ m4_include([m4/package_attrdev.m4])
m4_include([m4/package_dmapidev.m4])
m4_include([m4/package_gdbmdev.m4])
m4_include([m4/package_globals.m4])
+m4_include([m4/package_ssldev.m4])
m4_include([m4/package_utilies.m4])
m4_include([m4/package_uuiddev.m4])
m4_include([m4/package_xfslibs.m4])
diff --git a/configure.ac b/configure.ac
index bfae106..bd48fd9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -70,6 +70,7 @@ in
AC_PACKAGE_WANT_FALLOCATE
AC_PACKAGE_WANT_LINUX_PRCTL_H
AC_PACKAGE_WANT_LINUX_FS_H
+ AC_PACKAGE_WANT_SSL
;;
esac
diff --git a/include/builddefs.in b/include/builddefs.in
index 6519c13..24f838f 100644
--- a/include/builddefs.in
+++ b/include/builddefs.in
@@ -61,6 +61,7 @@ ENABLE_SHARED = @enable_shared@
HAVE_DB = @have_db@
HAVE_AIO = @have_aio@
HAVE_FALLOCATE = @have_fallocate@
+HAVE_SSL = @have_ssl@
HAVE_DMAPI = @have_dmapi@
HAVE_ATTR_LIST = @have_attr_list@
HAVE_FIEMAP = @have_fiemap@
diff --git a/m4/Makefile b/m4/Makefile
index 6c1d0e4..7fbff82 100644
--- a/m4/Makefile
+++ b/m4/Makefile
@@ -16,6 +16,7 @@ LSRCFILES = \
package_libcdev.m4 \
package_ncurses.m4 \
package_pthread.m4 \
+ package_ssldev.m4 \
package_types.m4 \
package_utilies.m4 \
package_uuiddev.m4 \
diff --git a/m4/package_ssldev.m4 b/m4/package_ssldev.m4
new file mode 100644
index 0000000..2eae3c5
--- /dev/null
+++ b/m4/package_ssldev.m4
@@ -0,0 +1,4 @@
+AC_DEFUN([AC_PACKAGE_WANT_SSL],
+ [ AC_CHECK_HEADERS(openssl/md5.h, [ have_ssl=true ], [ have_ssl=false ])
+ AC_SUBST(have_ssl)
+ ])
diff --git a/src/Makefile b/src/Makefile
index cc679e8..b2dfdcb 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -56,6 +56,14 @@ ifeq ($(HAVE_AIO), true)
SUBDIRS += aio-dio-regress
endif
+ifeq ($(HAVE_SSL), true)
+TARGETS += fssum
+LLDLIBS += -lssl -lcrypto
+ifeq ($(PKG_PLATFORM),linux)
+CFLAGS += -D__LINUX__
+endif
+endif
+
CFILES = $(TARGETS:=.c)
LDIRT = $(TARGETS)
diff --git a/src/fssum.c b/src/fssum.c
new file mode 100644
index 0000000..c75ff8b
--- /dev/null
+++ b/src/fssum.c
@@ -0,0 +1,828 @@
+/*
+ * Copyright (C) 2012 STRATO AG. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ */
+#ifdef __LINUX__
+#define _BSD_SOURCE
+#define _LARGEFILE64_SOURCE
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef __SOLARIS__
+#include <sys/mkdev.h>
+#endif
+#include <openssl/md5.h>
+#include <netinet/in.h>
+#include <inttypes.h>
+#include <assert.h>
+
+#define CS_SIZE 16
+#define CHUNKS 128
+
+#ifdef __LINUX__
+#ifndef SEEK_DATA
+#define SEEK_DATA 3
+#define SEEK_HOLE 4
+#endif
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+#define htonll(x) __bswap_64 (x)
+#endif
+#endif
+
+/* TODO: add hardlink recognition */
+/* TODO: add xattr/acl */
+
+struct excludes {
+ char *path;
+ int len;
+};
+
+typedef struct _sum {
+ MD5_CTX md5;
+ unsigned char out[16];
+} sum_t;
+
+typedef int (*sum_file_data_t)(int fd, sum_t *dst);
+
+int gen_manifest = 0;
+int in_manifest = 0;
+char *checksum = NULL;
+struct excludes *excludes;
+int n_excludes = 0;
+int verbose = 0;
+FILE *out_fp;
+FILE *in_fp;
+
+enum _flags {
+ FLAG_UID,
+ FLAG_GID,
+ FLAG_MODE,
+ FLAG_ATIME,
+ FLAG_MTIME,
+ FLAG_CTIME,
+ FLAG_DATA,
+ FLAG_OPEN_ERROR,
+ FLAG_STRUCTURE,
+ NUM_FLAGS
+};
+
+const char flchar[] = "ugoamcdes";
+char line[65536];
+
+int flags[NUM_FLAGS] = {1, 1, 1, 1, 1, 0, 1, 0, 0};
+
+char *
+getln(char *buf, int size, FILE *fp)
+{
+ char *p;
+ int l;
+
+ p = fgets(buf, size, fp);
+ if (!p)
+ return NULL;
+
+ l = strlen(p);
+ while(l > 0 && (p[l - 1] == '\n' || p[l - 1] == '\r'))
+ p[--l] = 0;
+
+ return p;
+}
+
+void
+parse_flag(int c)
+{
+ int i;
+ int is_upper = 0;
+
+ if (c >= 'A' && c <= 'Z') {
+ is_upper = 1;
+ c += 'a' - 'A';
+ }
+ for (i = 0; flchar[i]; ++i) {
+ if (flchar[i] == c) {
+ flags[i] = is_upper ? 0 : 1;
+ return;
+ }
+ }
+ fprintf(stderr, "unrecognized flag %c\n", c);
+ exit(-1);
+}
+
+void
+parse_flags(char *p)
+{
+ while (*p)
+ parse_flag(*p++);
+}
+
+void
+usage(void)
+{
+ fprintf(stderr, "usage: fssum <options> <path>\n");
+ fprintf(stderr, " options:\n");
+ fprintf(stderr, " -f : write out a full manifest file\n");
+ fprintf(stderr, " -w <file> : send output to file\n");
+ fprintf(stderr, " -v : verbose mode (debugging only)\n");
+ fprintf(stderr,
+ " -r <file> : read checksum or manifest from file\n");
+ fprintf(stderr, " -[ugoamcde] : specify which fields to include in checksum calculation.\n");
+ fprintf(stderr, " u : include uid\n");
+ fprintf(stderr, " g : include gid\n");
+ fprintf(stderr, " o : include mode\n");
+ fprintf(stderr, " m : include mtime\n");
+ fprintf(stderr, " a : include atime\n");
+ fprintf(stderr, " c : include ctime\n");
+ fprintf(stderr, " d : include file data\n");
+ fprintf(stderr, " e : include open errors (aborts otherwise)\n");
+ fprintf(stderr, " s : include block structure (holes)\n");
+ fprintf(stderr, " -[UGOAMCDES]: exclude respective field from calculation\n");
+ fprintf(stderr, " -n : reset all flags\n");
+ fprintf(stderr, " -N : set all flags\n");
+ fprintf(stderr, " -x path : exclude path when building checksum (multiple ok)\n");
+ fprintf(stderr, " -h : this help\n\n");
+ fprintf(stderr, "The default field mask is ugoamCdES. If the checksum/manifest is read from a\n");
+ fprintf(stderr, "file, the mask is taken from there and the values given on the command line\n");
+ fprintf(stderr, "are ignored.\n");
+ exit(-1);
+}
+
+static char buf[65536];
+
+void *
+alloc(size_t sz)
+{
+ void *p = malloc(sz);
+
+ if (!p) {
+ fprintf(stderr, "malloc failed\n");
+ exit(-1);
+ }
+
+ return p;
+}
+
+void
+sum_init(sum_t *cs)
+{
+ MD5_Init(&cs->md5);
+}
+
+void
+sum_fini(sum_t *cs)
+{
+ MD5_Final(cs->out, &cs->md5);
+}
+
+void
+sum_add(sum_t *cs, void *buf, int size)
+{
+ MD5_Update(&cs->md5, buf, size);
+}
+
+void
+sum_add_sum(sum_t *dst, sum_t *src)
+{
+ sum_add(dst, src->out, sizeof(src->out));
+}
+
+void
+sum_add_u64(sum_t *dst, uint64_t val)
+{
+ uint64_t v = htonll(val);
+ sum_add(dst, &v, sizeof(v));
+}
+
+void
+sum_add_time(sum_t *dst, time_t t)
+{
+ sum_add_u64(dst, t);
+}
+
+char *
+sum_to_string(sum_t *dst)
+{
+ int i;
+ char *s = alloc(CS_SIZE * 2 + 1);
+
+ for (i = 0; i < CS_SIZE; ++i)
+ sprintf(s + i * 2, "%02x", dst->out[i]);
+
+ return s;
+}
+
+int
+sum_file_data_permissive(int fd, sum_t *dst)
+{
+ int ret;
+ off_t pos;
+ off_t old;
+ int i;
+ uint64_t zeros = 0;
+
+ pos = lseek(fd, 0, SEEK_CUR);
+ if (pos == (off_t)-1)
+ return errno == ENXIO ? 0 : -2;
+
+ while (1) {
+ old = pos;
+ pos = lseek(fd, pos, SEEK_DATA);
+ if (pos == (off_t)-1) {
+ if (errno == ENXIO) {
+ ret = 0;
+ pos = lseek(fd, 0, SEEK_END);
+ if (pos != (off_t)-1)
+ zeros += pos - old;
+ } else {
+ ret = -2;
+ }
+ break;
+ }
+ ret = read(fd, buf, sizeof(buf));
+ assert(ret); /* eof found by lseek */
+ if (ret <= 0)
+ break;
+ if (old < pos) /* hole */
+ zeros += pos - old;
+ for (i = 0; i < ret; ++i) {
+ for (old = i; buf[i] == 0 && i < ret; ++i)
+ ;
+ if (old < i) /* code like a hole */
+ zeros += i - old;
+ if (i == ret)
+ break;
+ if (zeros) {
+ if (verbose >= 2)
+ fprintf(stderr,
+ "adding %llu zeros to sum\n",
+ (unsigned long long)zeros);
+ sum_add_u64(dst, 0);
+ sum_add_u64(dst, zeros);
+ zeros = 0;
+ }
+ for (old = i; buf[i] != 0 && i < ret; ++i)
+ ;
+ if (verbose >= 2)
+ fprintf(stderr, "adding %u non-zeros to sum\n",
+ i - (int)old);
+ sum_add(dst, buf + old, i - old);
+ }
+ pos += ret;
+ }
+
+ if (zeros) {
+ if (verbose >= 2)
+ fprintf(stderr,
+ "adding %llu zeros to sum (finishing)\n",
+ (unsigned long long)zeros);
+ sum_add_u64(dst, 0);
+ sum_add_u64(dst, zeros);
+ }
+
+ return ret;
+}
+
+int
+sum_file_data_strict(int fd, sum_t *dst)
+{
+ int ret;
+ off_t pos;
+
+ pos = lseek(fd, 0, SEEK_CUR);
+ if (pos == (off_t)-1)
+ return errno == ENXIO ? 0 : -2;
+
+ while (1) {
+ pos = lseek(fd, pos, SEEK_DATA);
+ if (pos == (off_t)-1)
+ return errno == ENXIO ? 0 : -2;
+ ret = read(fd, buf, sizeof(buf));
+ assert(ret); /* eof found by lseek */
+ if (ret <= 0)
+ return ret;
+ if (verbose >= 2)
+ fprintf(stderr,
+ "adding to sum at file offset %llu, %d bytes\n",
+ (unsigned long long)pos, ret);
+ sum_add_u64(dst, (uint64_t)pos);
+ sum_add(dst, buf, ret);
+ pos += ret;
+ }
+}
+
+char *
+escape(char *in)
+{
+ char *out = alloc(strlen(in) * 3 + 1);
+ char *src = in;
+ char *dst = out;
+
+ for (; *src; ++src) {
+ if (*src >= 32 && *src < 127 && *src != '\\') {
+ *dst++ = *src;
+ } else {
+ sprintf(dst, "\\%02x", (unsigned char)*src);
+ dst += 3;
+ }
+ }
+ *dst = 0;
+
+ return out;
+}
+
+void
+excess_file(const char *fn)
+{
+ printf("only in local fs: %s\n", fn);
+}
+
+void
+missing_file(const char *fn)
+{
+ printf("only in remote fs: %s\n", fn);
+}
+
+int
+pathcmp(const char *a, const char *b)
+{
+ int len_a = strlen(a);
+ int len_b = strlen(b);
+
+ /*
+ * as the containing directory is sent after the files, it has to
+ * come out bigger in the comparison.
+ */
+ if (len_a < len_b && a[len_a - 1] == '/' && strncmp(a, b, len_a) == 0)
+ return 1;
+ if (len_a > len_b && b[len_b - 1] == '/' && strncmp(a, b, len_b) == 0)
+ return -1;
+
+ return strcmp(a, b);
+}
+
+void
+check_match(char *fn, char *local_m, char *remote_m,
+ char *local_c, char *remote_c)
+{
+ int match_m = !strcmp(local_m, remote_m);
+ int match_c = !strcmp(local_c, remote_c);
+
+ if (match_m && !match_c) {
+ printf("data mismatch in %s\n", fn);
+ } else if (!match_m && match_c) {
+ printf("metadata mismatch in %s\n", fn);
+ } else if (!match_m && !match_c) {
+ printf("metadata and data mismatch in %s\n", fn);
+ }
+}
+
+char *prev_fn;
+char *prev_m;
+char *prev_c;
+void
+check_manifest(char *fn, char *m, char *c, int last_call)
+{
+ char *rem_m;
+ char *rem_c;
+ char *l;
+ int cmp;
+
+ if (prev_fn) {
+ if (last_call)
+ cmp = -1;
+ else
+ cmp = pathcmp(prev_fn, fn);
+ if (cmp > 0) {
+ excess_file(fn);
+ return;
+ } else if (cmp < 0) {
+ missing_file(prev_fn);
+ } else {
+ check_match(fn, m, prev_m, c, prev_c);
+ }
+ free(prev_fn);
+ free(prev_m);
+ free(prev_c);
+ prev_fn = NULL;
+ prev_m = NULL;
+ prev_c = NULL;
+ if (cmp == 0)
+ return;
+ }
+ while ((l = getln(line, sizeof(line), in_fp))) {
+ rem_c = strrchr(l, ' ');
+ if (!rem_c) {
+ /* final cs */
+ checksum = strdup(l);
+ break;
+ }
+ if (rem_c == l) {
+malformed:
+ fprintf(stderr, "malformed input\n");
+ exit(-1);
+ }
+ *rem_c++ = 0;
+ rem_m = strrchr(l, ' ');
+ if (!rem_m)
+ goto malformed;
+ *rem_m++ = 0;
+
+ if (last_call)
+ cmp = -1;
+ else
+ cmp = pathcmp(l, fn);
+ if (cmp == 0) {
+ check_match(fn, m, rem_m, c, rem_c);
+ return;
+ } else if (cmp > 0) {
+ excess_file(fn);
+ prev_fn = strdup(l);
+ prev_m = strdup(rem_m);
+ prev_c = strdup(rem_c);
+ return;
+ }
+ missing_file(l);
+ }
+ if (!last_call)
+ excess_file(fn);
+}
+
+int
+namecmp(const void *aa, const void *bb)
+{
+ char * const *a = aa;
+ char * const *b = bb;
+
+ return strcmp(*a, *b);
+}
+
+void
+sum(int dirfd, int level, sum_t *dircs, char *path_prefix, char *path_in)
+{
+ DIR *d;
+ struct dirent *de;
+ char **namelist = NULL;
+ int alloclen = 0;
+ int entries = 0;
+ int i;
+ int ret;
+ int fd;
+ int excl;
+ sum_file_data_t sum_file_data = flags[FLAG_STRUCTURE] ?
+ sum_file_data_strict : sum_file_data_permissive;
+
+ d = fdopendir(dirfd);
+ if (!d) {
+ perror("opendir");
+ exit(-1);
+ }
+ while((de = readdir(d))) {
+ if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
+ continue;
+ if (entries == alloclen) {
+ alloclen += CHUNKS;
+ namelist = realloc(namelist,
+ alloclen * sizeof(*namelist));
+ if (!namelist) {
+ fprintf(stderr, "malloc failed\n");
+ exit(-1);
+ }
+ }
+ namelist[entries] = strdup(de->d_name);
+ if (!namelist[entries]) {
+ fprintf(stderr, "malloc failed\n");
+ exit(-1);
+ }
+ ++entries;
+ }
+ qsort(namelist, entries, sizeof(*namelist), namecmp);
+ for (i = 0; i < entries; ++i) {
+ struct stat64 st;
+ sum_t cs;
+ sum_t meta;
+ char *path;
+
+ sum_init(&cs);
+ sum_init(&meta);
+ path = alloc(strlen(path_in) + strlen(namelist[i]) + 3);
+ sprintf(path, "%s/%s", path_in, namelist[i]);
+ for (excl = 0; excl < n_excludes; ++excl) {
+ if (strncmp(excludes[excl].path, path,
+ excludes[excl].len) == 0)
+ goto next;
+ }
+
+ ret = fchdir(dirfd);
+ if (ret == -1) {
+ perror("fchdir");
+ exit(-1);
+ }
+ ret = lstat64(namelist[i], &st);
+ if (ret) {
+ fprintf(stderr, "stat failed for %s/%s: %s\n",
+ path_prefix, path, strerror(errno));
+ exit(-1);
+ }
+ sum_add_u64(&meta, level);
+ sum_add(&meta, namelist[i], strlen(namelist[i]));
+ if (!S_ISDIR(st.st_mode))
+ sum_add_u64(&meta, st.st_nlink);
+ if (flags[FLAG_UID])
+ sum_add_u64(&meta, st.st_uid);
+ if (flags[FLAG_GID])
+ sum_add_u64(&meta, st.st_gid);
+ if (flags[FLAG_MODE])
+ sum_add_u64(&meta, st.st_mode);
+ if (flags[FLAG_ATIME])
+ sum_add_time(&meta, st.st_atime);
+ if (flags[FLAG_MTIME])
+ sum_add_time(&meta, st.st_mtime);
+ if (flags[FLAG_CTIME])
+ sum_add_time(&meta, st.st_ctime);
+ if (S_ISDIR(st.st_mode)) {
+ fd = openat(dirfd, namelist[i], 0);
+ if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
+ sum_add_u64(&meta, errno);
+ } else if (fd == -1) {
+ fprintf(stderr, "open failed for %s/%s: %s\n",
+ path_prefix, path, strerror(errno));
+ exit(-1);
+ } else {
+ sum(fd, level + 1, &cs, path_prefix, path);
+ close(fd);
+ }
+ } else if (S_ISREG(st.st_mode)) {
+ sum_add_u64(&meta, st.st_size);
+ if (flags[FLAG_DATA]) {
+ if (verbose)
+ fprintf(stderr, "file %s\n",
+ namelist[i]);
+ fd = openat(dirfd, namelist[i], 0);
+ if (fd == -1 && flags[FLAG_OPEN_ERROR]) {
+ sum_add_u64(&meta, errno);
+ } else if (fd == -1) {
+ fprintf(stderr,
+ "open failed for %s/%s: %s\n",
+ path_prefix, path,
+ strerror(errno));
+ exit(-1);
+ }
+ if (fd != -1) {
+ ret = sum_file_data(fd, &cs);
+ if (ret < 0) {
+ fprintf(stderr,
+ "read failed for "
+ "%s/%s: %s\n",
+ path_prefix, path,
+ strerror(errno));
+ exit(-1);
+ }
+ close(fd);
+ }
+ }
+ } else if (S_ISLNK(st.st_mode)) {
+ ret = readlink(namelist[i], buf, sizeof(buf));
+ if (ret == -1) {
+ perror("readlink");
+ exit(-1);
+ }
+ sum_add(&cs, buf, ret);
+ } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
+ sum_add_u64(&cs, major(st.st_rdev));
+ sum_add_u64(&cs, minor(st.st_rdev));
+ }
+ sum_fini(&cs);
+ sum_fini(&meta);
+ if (gen_manifest || in_manifest) {
+ char *fn;
+ char *m;
+ char *c;
+
+ if (S_ISDIR(st.st_mode))
+ strcat(path, "/");
+ fn = escape(path);
+ m = sum_to_string(&meta);
+ c = sum_to_string(&cs);
+
+ if (gen_manifest)
+ fprintf(out_fp, "%s %s %s\n", fn, m, c);
+ if (in_manifest)
+ check_manifest(fn, m, c, 0);
+ free(c);
+ free(m);
+ free(fn);
+ }
+ sum_add_sum(dircs, &cs);
+ sum_add_sum(dircs, &meta);
+next:
+ free(path);
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ extern char *optarg;
+ extern int optind;
+ int c;
+ char *path;
+ int fd;
+ sum_t cs;
+ char flagstring[sizeof(flchar)];
+ int i;
+ int plen;
+ int elen;
+ int n_flags = 0;
+ const char *allopts = "heEfuUgGoOaAmMcCdDsSnNw:r:vx:";
+
+ out_fp = stdout;
+ while ((c = getopt(argc, argv, allopts)) != EOF) {
+ switch(c) {
+ case 'f':
+ gen_manifest = 1;
+ break;
+ case 'u':
+ case 'U':
+ case 'g':
+ case 'G':
+ case 'o':
+ case 'O':
+ case 'a':
+ case 'A':
+ case 'm':
+ case 'M':
+ case 'c':
+ case 'C':
+ case 'd':
+ case 'D':
+ case 'e':
+ case 'E':
+ case 's':
+ case 'S':
+ ++n_flags;
+ parse_flag(c);
+ break;
+ case 'n':
+ for (i = 0; i < NUM_FLAGS; ++i)
+ flags[i] = 0;
+ break;
+ case 'N':
+ for (i = 0; i < NUM_FLAGS; ++i)
+ flags[i] = 1;
+ break;
+ case 'w':
+ out_fp = fopen(optarg, "w");
+ if (!out_fp) {
+ fprintf(stderr,
+ "failed to open output file: %s\n",
+ strerror(errno));
+ exit(-1);
+ }
+ break;
+ case 'r':
+ in_fp = fopen(optarg, "r");
+ if (!in_fp) {
+ fprintf(stderr,
+ "failed to open input file: %s\n",
+ strerror(errno));
+ exit(-1);
+ }
+ break;
+ case 'x':
+ ++n_excludes;
+ excludes = realloc(excludes,
+ sizeof(*excludes) * n_excludes);
+ if (!excludes) {
+ fprintf(stderr,
+ "failed to alloc exclude space\n");
+ exit(-1);
+ }
+ excludes[n_excludes - 1].path = optarg;
+ break;
+ case 'v':
+ ++verbose;
+ break;
+ case 'h':
+ case '?':
+ usage();
+ }
+ }
+
+ if (optind + 1 != argc) {
+ fprintf(stderr, "missing path\n");
+ usage();
+ }
+
+ if (in_fp) {
+ char *l = getln(line, sizeof(line), in_fp);
+ char *p;
+
+ if (l == NULL) {
+ fprintf(stderr, "failed to read line from input\n");
+ exit(-1);
+ }
+ if (strncmp(l, "Flags: ", 7) == 0) {
+ l += 7;
+ in_manifest = 1;
+ parse_flags(l);
+ } else if ((p = strchr(l, ':'))) {
+ *p++ = 0;
+ parse_flags(l);
+ checksum = strdup(p);
+ } else {
+ fprintf(stderr, "invalid input file format\n");
+ exit(-1);
+ }
+ if (n_flags)
+ fprintf(stderr, "warning: "
+ "command line flags ignored in -r mode\n");
+ }
+ strcpy(flagstring, flchar);
+ for (i = 0; i < NUM_FLAGS; ++i) {
+ if (flags[i] == 0)
+ flagstring[i] -= 'a' - 'A';
+ }
+
+ path = argv[optind];
+ plen = strlen(path);
+ if (path[plen - 1] == '/') {
+ --plen;
+ path[plen] = '\0';
+ }
+
+ for (i = 0; i < n_excludes; ++i) {
+ if (strncmp(path, excludes[i].path, plen) != 0)
+ fprintf(stderr,
+ "warning: exclude %s outside of path %s\n",
+ excludes[i].path, path);
+ else
+ excludes[i].path += plen;
+ elen = strlen(excludes[i].path);
+ if (excludes[i].path[elen - 1] == '/')
+ --elen;
+ excludes[i].path[elen] = '\0';
+ excludes[i].len = elen;
+ }
+
+ fd = open(path, O_RDONLY);
+ if (fd == -1) {
+ fprintf(stderr, "failed to open %s: %s\n", path,
+ strerror(errno));
+ exit(-1);
+ }
+
+ if (gen_manifest)
+ fprintf(out_fp, "Flags: %s\n", flagstring);
+
+ sum_init(&cs);
+ sum(fd, 1, &cs, path, "");
+ sum_fini(&cs);
+
+ close(fd);
+ if (in_manifest)
+ check_manifest("", "", "", 1);
+
+ if (!checksum) {
+ if (in_manifest) {
+ fprintf(stderr, "malformed input\n");
+ exit(-1);
+ }
+ if (!gen_manifest)
+ fprintf(out_fp, "%s:", flagstring);
+
+ fprintf(out_fp, "%s\n", sum_to_string(&cs));
+ } else {
+ if (strcmp(checksum, sum_to_string(&cs)) == 0) {
+ printf("OK\n");
+ exit(0);
+ } else {
+ printf("FAIL\n");
+ exit(1);
+ }
+ }
+
+ exit(0);
+}
--
1.7.2.5
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 2/2] xfstests btrfs/316: test send / receive
2013-08-13 17:24 ` Jan Schmidt
@ 2013-08-13 17:24 ` Jan Schmidt
-1 siblings, 0 replies; 10+ messages in thread
From: Jan Schmidt @ 2013-08-13 17:24 UTC (permalink / raw)
To: xfs; +Cc: linux-btrfs, sbehrens, sandeen
Basic send / receive functionality test for btrfs. Requires current
version of fsstress built (-x support). Relies on fssum tool but can
skip the test if it failed to build.
Signed-off-by: Jan Schmidt <list.xfs@jan-o-sch.net>
Reviewed-by: Josef Bacik <jbacik@fusionio.com>
---
tests/btrfs/316 | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/btrfs/316.out | 4 ++
tests/btrfs/group | 1 +
3 files changed, 121 insertions(+), 0 deletions(-)
create mode 100755 tests/btrfs/316
create mode 100644 tests/btrfs/316.out
diff --git a/tests/btrfs/316 b/tests/btrfs/316
new file mode 100755
index 0000000..b3af7d9
--- /dev/null
+++ b/tests/btrfs/316
@@ -0,0 +1,116 @@
+#! /bin/bash
+# FSQA Test No. 316
+#
+# Run fsstress to create a reasonably strange file system, make a
+# snapshot (base) and run more fsstress. Then take another snapshot
+# (incr) and send both snapshots to a temp file. Remake the file
+# system and receive from the files. Check both states with fssum.
+#
+#-----------------------------------------------------------------------
+# Copyright (C) 2013 STRATO. All rights reserved.
+#
+# 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.
+#
+# This program is distributed in the hope that it would 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 the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+#-----------------------------------------------------------------------
+#
+# creator
+owner=list.btrfs@jan-o-sch.net
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=`mktemp -d`
+status=1
+
+_cleanup()
+{
+ echo "*** unmount"
+ umount $SCRATCH_MNT 2>/dev/null
+ rm -f $tmp.*
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+
+# real QA test starts here
+_need_to_be_root
+_supported_fs btrfs
+_supported_os Linux
+_require_scratch
+_require_seek_data_hole
+
+FSSUM_PROG=$here/src/fssum
+[ -x $FSSUM_PROG ] || _notrun "fssum not built"
+
+rm -f $seqres.full
+
+workout()
+{
+ fsz=$1
+ ops=$2
+
+ umount $SCRATCH_DEV >/dev/null 2>&1
+ echo "*** mkfs -dsize=$fsz" >>$seqres.full
+ echo "" >>$seqres.full
+ _scratch_mkfs_sized $fsz >>$seqres.full 2>&1 \
+ || _fail "size=$fsz mkfs failed"
+ run_check _scratch_mount "-o noatime"
+
+ run_check $FSSTRESS_PROG -d $SCRATCH_MNT -n $ops $FSSTRESS_AVOID -x \
+ "$BTRFS_UTIL_PROG subvol snap -r $SCRATCH_MNT $SCRATCH_MNT/base"
+
+ run_check $BTRFS_UTIL_PROG subvol snap -r $SCRATCH_MNT $SCRATCH_MNT/incr
+
+ echo "# $BTRFS_UTIL_PROG send $SCRATCH_MNT/base > $tmp/base.snap" \
+ >> $seqres.full
+ $BTRFS_UTIL_PROG send $SCRATCH_MNT/base > $tmp/base.snap 2>> $seqres.full \
+ || _fail "failed: '$@'"
+ echo "# $BTRFS_UTIL_PROG send -p $SCRATCH_MNT/base\
+ $SCRATCH_MNT/incr > $tmp/incr.snap" >> $seqres.full
+ $BTRFS_UTIL_PROG send -p $SCRATCH_MNT/base \
+ $SCRATCH_MNT/incr > $tmp/incr.snap 2>> $seqres.full \
+ || _fail "failed: '$@'"
+
+ run_check $FSSUM_PROG -A -f -w $tmp/base.fssum $SCRATCH_MNT/base
+ run_check $FSSUM_PROG -A -f -w $tmp/incr.fssum -x $SCRATCH_MNT/incr/base \
+ $SCRATCH_MNT/incr
+
+ umount $SCRATCH_DEV >/dev/null 2>&1
+ echo "*** mkfs -dsize=$fsz" >>$seqres.full
+ echo "" >>$seqres.full
+ _scratch_mkfs_sized $fsz >>$seqres.full 2>&1 \
+ || _fail "size=$fsz mkfs failed"
+ run_check _scratch_mount "-o noatime"
+
+ run_check $BTRFS_UTIL_PROG receive $SCRATCH_MNT < $tmp/base.snap
+ run_check $FSSUM_PROG -r $tmp/base.fssum $SCRATCH_MNT/base
+
+ run_check $BTRFS_UTIL_PROG receive $SCRATCH_MNT < $tmp/incr.snap
+ run_check $FSSUM_PROG -r $tmp/incr.fssum $SCRATCH_MNT/incr
+}
+
+echo "*** test send / receive"
+
+fssize=`expr 2000 \* 1024 \* 1024`
+ops=200
+
+workout $fssize $ops
+
+echo "*** done"
+status=0
+exit
diff --git a/tests/btrfs/316.out b/tests/btrfs/316.out
new file mode 100644
index 0000000..4564c85
--- /dev/null
+++ b/tests/btrfs/316.out
@@ -0,0 +1,4 @@
+QA output created by 316
+*** test send / receive
+*** done
+*** unmount
diff --git a/tests/btrfs/group b/tests/btrfs/group
index bc6c256..11d708a 100644
--- a/tests/btrfs/group
+++ b/tests/btrfs/group
@@ -9,3 +9,4 @@
276 auto rw metadata
284 auto
307 auto quick
+316 auto rw metadata
--
1.7.2.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 2/2] xfstests btrfs/316: test send / receive
@ 2013-08-13 17:24 ` Jan Schmidt
0 siblings, 0 replies; 10+ messages in thread
From: Jan Schmidt @ 2013-08-13 17:24 UTC (permalink / raw)
To: xfs; +Cc: sandeen, sbehrens, linux-btrfs
Basic send / receive functionality test for btrfs. Requires current
version of fsstress built (-x support). Relies on fssum tool but can
skip the test if it failed to build.
Signed-off-by: Jan Schmidt <list.xfs@jan-o-sch.net>
Reviewed-by: Josef Bacik <jbacik@fusionio.com>
---
tests/btrfs/316 | 116 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/btrfs/316.out | 4 ++
tests/btrfs/group | 1 +
3 files changed, 121 insertions(+), 0 deletions(-)
create mode 100755 tests/btrfs/316
create mode 100644 tests/btrfs/316.out
diff --git a/tests/btrfs/316 b/tests/btrfs/316
new file mode 100755
index 0000000..b3af7d9
--- /dev/null
+++ b/tests/btrfs/316
@@ -0,0 +1,116 @@
+#! /bin/bash
+# FSQA Test No. 316
+#
+# Run fsstress to create a reasonably strange file system, make a
+# snapshot (base) and run more fsstress. Then take another snapshot
+# (incr) and send both snapshots to a temp file. Remake the file
+# system and receive from the files. Check both states with fssum.
+#
+#-----------------------------------------------------------------------
+# Copyright (C) 2013 STRATO. All rights reserved.
+#
+# 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.
+#
+# This program is distributed in the hope that it would 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 the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+#-----------------------------------------------------------------------
+#
+# creator
+owner=list.btrfs@jan-o-sch.net
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=`mktemp -d`
+status=1
+
+_cleanup()
+{
+ echo "*** unmount"
+ umount $SCRATCH_MNT 2>/dev/null
+ rm -f $tmp.*
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+
+# real QA test starts here
+_need_to_be_root
+_supported_fs btrfs
+_supported_os Linux
+_require_scratch
+_require_seek_data_hole
+
+FSSUM_PROG=$here/src/fssum
+[ -x $FSSUM_PROG ] || _notrun "fssum not built"
+
+rm -f $seqres.full
+
+workout()
+{
+ fsz=$1
+ ops=$2
+
+ umount $SCRATCH_DEV >/dev/null 2>&1
+ echo "*** mkfs -dsize=$fsz" >>$seqres.full
+ echo "" >>$seqres.full
+ _scratch_mkfs_sized $fsz >>$seqres.full 2>&1 \
+ || _fail "size=$fsz mkfs failed"
+ run_check _scratch_mount "-o noatime"
+
+ run_check $FSSTRESS_PROG -d $SCRATCH_MNT -n $ops $FSSTRESS_AVOID -x \
+ "$BTRFS_UTIL_PROG subvol snap -r $SCRATCH_MNT $SCRATCH_MNT/base"
+
+ run_check $BTRFS_UTIL_PROG subvol snap -r $SCRATCH_MNT $SCRATCH_MNT/incr
+
+ echo "# $BTRFS_UTIL_PROG send $SCRATCH_MNT/base > $tmp/base.snap" \
+ >> $seqres.full
+ $BTRFS_UTIL_PROG send $SCRATCH_MNT/base > $tmp/base.snap 2>> $seqres.full \
+ || _fail "failed: '$@'"
+ echo "# $BTRFS_UTIL_PROG send -p $SCRATCH_MNT/base\
+ $SCRATCH_MNT/incr > $tmp/incr.snap" >> $seqres.full
+ $BTRFS_UTIL_PROG send -p $SCRATCH_MNT/base \
+ $SCRATCH_MNT/incr > $tmp/incr.snap 2>> $seqres.full \
+ || _fail "failed: '$@'"
+
+ run_check $FSSUM_PROG -A -f -w $tmp/base.fssum $SCRATCH_MNT/base
+ run_check $FSSUM_PROG -A -f -w $tmp/incr.fssum -x $SCRATCH_MNT/incr/base \
+ $SCRATCH_MNT/incr
+
+ umount $SCRATCH_DEV >/dev/null 2>&1
+ echo "*** mkfs -dsize=$fsz" >>$seqres.full
+ echo "" >>$seqres.full
+ _scratch_mkfs_sized $fsz >>$seqres.full 2>&1 \
+ || _fail "size=$fsz mkfs failed"
+ run_check _scratch_mount "-o noatime"
+
+ run_check $BTRFS_UTIL_PROG receive $SCRATCH_MNT < $tmp/base.snap
+ run_check $FSSUM_PROG -r $tmp/base.fssum $SCRATCH_MNT/base
+
+ run_check $BTRFS_UTIL_PROG receive $SCRATCH_MNT < $tmp/incr.snap
+ run_check $FSSUM_PROG -r $tmp/incr.fssum $SCRATCH_MNT/incr
+}
+
+echo "*** test send / receive"
+
+fssize=`expr 2000 \* 1024 \* 1024`
+ops=200
+
+workout $fssize $ops
+
+echo "*** done"
+status=0
+exit
diff --git a/tests/btrfs/316.out b/tests/btrfs/316.out
new file mode 100644
index 0000000..4564c85
--- /dev/null
+++ b/tests/btrfs/316.out
@@ -0,0 +1,4 @@
+QA output created by 316
+*** test send / receive
+*** done
+*** unmount
diff --git a/tests/btrfs/group b/tests/btrfs/group
index bc6c256..11d708a 100644
--- a/tests/btrfs/group
+++ b/tests/btrfs/group
@@ -9,3 +9,4 @@
276 auto rw metadata
284 auto
307 auto quick
+316 auto rw metadata
--
1.7.2.5
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v4 0/2] xfstest btrfs/316: test send / receive
2013-08-13 17:24 ` Jan Schmidt
@ 2013-08-13 18:33 ` Eric Sandeen
-1 siblings, 0 replies; 10+ messages in thread
From: Eric Sandeen @ 2013-08-13 18:33 UTC (permalink / raw)
To: Jan Schmidt; +Cc: xfs, linux-btrfs, sbehrens
On 8/13/13 12:24 PM, Jan Schmidt wrote:
> These two patches add the announced tests for btrfs send / receive. As
> requested, the fssum tool is now included.
Thanks for the updates.
Both:
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
> --
> v1->v2:
> - included fssum
> - test number is now 316 (was 314)
> v2->v3:
> - added missing -lcrypto to build fssum
> - removed obsolete change in README now that fssum is included
> - fixed comment in test/btrfs/316's header (314 -> 316)
> v3->v4:
> - build fssum with help of autotools only if libssl is available
> - removed clumsy OPT_TARGETS in src/Makefile
> - added #define directives for SEEK_DATA and SEEK_HOLE to fssum.c
>
> Jan Schmidt (2):
> xfstests: add fssum tool
> xfstests btrfs/316: test send / receive
>
> .gitignore | 1 +
> aclocal.m4 | 1 +
> configure.ac | 1 +
> include/builddefs.in | 1 +
> m4/Makefile | 1 +
> m4/package_ssldev.m4 | 4 +
> src/Makefile | 8 +
> src/fssum.c | 828 ++++++++++++++++++++++++++++++++++++++++++++++++++
> tests/btrfs/316 | 116 +++++++
> tests/btrfs/316.out | 4 +
> tests/btrfs/group | 1 +
> 11 files changed, 966 insertions(+), 0 deletions(-)
> create mode 100644 m4/package_ssldev.m4
> create mode 100644 src/fssum.c
> create mode 100755 tests/btrfs/316
> create mode 100644 tests/btrfs/316.out
>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 0/2] xfstest btrfs/316: test send / receive
@ 2013-08-13 18:33 ` Eric Sandeen
0 siblings, 0 replies; 10+ messages in thread
From: Eric Sandeen @ 2013-08-13 18:33 UTC (permalink / raw)
To: Jan Schmidt; +Cc: sbehrens, linux-btrfs, xfs
On 8/13/13 12:24 PM, Jan Schmidt wrote:
> These two patches add the announced tests for btrfs send / receive. As
> requested, the fssum tool is now included.
Thanks for the updates.
Both:
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
> --
> v1->v2:
> - included fssum
> - test number is now 316 (was 314)
> v2->v3:
> - added missing -lcrypto to build fssum
> - removed obsolete change in README now that fssum is included
> - fixed comment in test/btrfs/316's header (314 -> 316)
> v3->v4:
> - build fssum with help of autotools only if libssl is available
> - removed clumsy OPT_TARGETS in src/Makefile
> - added #define directives for SEEK_DATA and SEEK_HOLE to fssum.c
>
> Jan Schmidt (2):
> xfstests: add fssum tool
> xfstests btrfs/316: test send / receive
>
> .gitignore | 1 +
> aclocal.m4 | 1 +
> configure.ac | 1 +
> include/builddefs.in | 1 +
> m4/Makefile | 1 +
> m4/package_ssldev.m4 | 4 +
> src/Makefile | 8 +
> src/fssum.c | 828 ++++++++++++++++++++++++++++++++++++++++++++++++++
> tests/btrfs/316 | 116 +++++++
> tests/btrfs/316.out | 4 +
> tests/btrfs/group | 1 +
> 11 files changed, 966 insertions(+), 0 deletions(-)
> create mode 100644 m4/package_ssldev.m4
> create mode 100644 src/fssum.c
> create mode 100755 tests/btrfs/316
> create mode 100644 tests/btrfs/316.out
>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 0/2] xfstest btrfs/316: test send / receive
2013-08-13 18:33 ` Eric Sandeen
@ 2013-08-13 22:31 ` Rich Johnston
-1 siblings, 0 replies; 10+ messages in thread
From: Rich Johnston @ 2013-08-13 22:31 UTC (permalink / raw)
To: Eric Sandeen; +Cc: Jan Schmidt, sbehrens, linux-btrfs, xfs
On 08/13/2013 01:33 PM, Eric Sandeen wrote:
> On 8/13/13 12:24 PM, Jan Schmidt wrote:
>> These two patches add the announced tests for btrfs send / receive. As
>> requested, the fssum tool is now included.
>
>
> Thanks for the updates.
>
> Both:
> Reviewed-by: Eric Sandeen <sandeen@redhat.com>
>
Thanks Jan, this has been committed.
--Rich
commit af86f5668eb164d1db52d1bf65673ba51d6fc75a
Author: Jan Schmidt <list.xfs@jan-o-sch.net>
Date: Tue Aug 13 17:24:18 2013 +0000
xfstests btrfs/007: test send / receive
Basic send / receive functionality test for btrfs. Requires current
version of fsstress built (-x support). Relies on fssum tool but can
skip the test if it failed to build.
Signed-off-by: Jan Schmidt <list.xfs@jan-o-sch.net>
Reviewed-by: Josef Bacik <jbacik@fusionio.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Rich Johnston <rjohnston@sgi.com>
[rjohnston: renumbered test from 316 to 007]
commit df0fd18101b625aad690d4cd3bb4ba7e7d1d99dc
Author: Jan Schmidt <list.xfs@jan-o-sch.net>
Date: Tue Aug 13 17:24:17 2013 +0000
xfstests: add fssum tool
fssum is a tool to build a recursive checksum for a file system.
The home
repository of fssum is
git://git.kernel.org/pub/scm/linux/kernel/git/arne/far-progs.git
Signed-off-by: Jan Schmidt <list.xfs@jan-o-sch.net>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Rich Johnston <rjohnston@sgi.com>
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 0/2] xfstest btrfs/316: test send / receive
@ 2013-08-13 22:31 ` Rich Johnston
0 siblings, 0 replies; 10+ messages in thread
From: Rich Johnston @ 2013-08-13 22:31 UTC (permalink / raw)
To: Eric Sandeen; +Cc: Jan Schmidt, linux-btrfs, sbehrens, xfs
On 08/13/2013 01:33 PM, Eric Sandeen wrote:
> On 8/13/13 12:24 PM, Jan Schmidt wrote:
>> These two patches add the announced tests for btrfs send / receive. As
>> requested, the fssum tool is now included.
>
>
> Thanks for the updates.
>
> Both:
> Reviewed-by: Eric Sandeen <sandeen@redhat.com>
>
Thanks Jan, this has been committed.
--Rich
commit af86f5668eb164d1db52d1bf65673ba51d6fc75a
Author: Jan Schmidt <list.xfs@jan-o-sch.net>
Date: Tue Aug 13 17:24:18 2013 +0000
xfstests btrfs/007: test send / receive
Basic send / receive functionality test for btrfs. Requires current
version of fsstress built (-x support). Relies on fssum tool but can
skip the test if it failed to build.
Signed-off-by: Jan Schmidt <list.xfs@jan-o-sch.net>
Reviewed-by: Josef Bacik <jbacik@fusionio.com>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Rich Johnston <rjohnston@sgi.com>
[rjohnston: renumbered test from 316 to 007]
commit df0fd18101b625aad690d4cd3bb4ba7e7d1d99dc
Author: Jan Schmidt <list.xfs@jan-o-sch.net>
Date: Tue Aug 13 17:24:17 2013 +0000
xfstests: add fssum tool
fssum is a tool to build a recursive checksum for a file system.
The home
repository of fssum is
git://git.kernel.org/pub/scm/linux/kernel/git/arne/far-progs.git
Signed-off-by: Jan Schmidt <list.xfs@jan-o-sch.net>
Reviewed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Rich Johnston <rjohnston@sgi.com>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2013-08-13 22:31 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-13 17:24 [PATCH v4 0/2] xfstest btrfs/316: test send / receive Jan Schmidt
2013-08-13 17:24 ` Jan Schmidt
2013-08-13 17:24 ` [PATCH v4 1/2] xfstests: add fssum tool Jan Schmidt
2013-08-13 17:24 ` Jan Schmidt
2013-08-13 17:24 ` [PATCH v4 2/2] xfstests btrfs/316: test send / receive Jan Schmidt
2013-08-13 17:24 ` Jan Schmidt
2013-08-13 18:33 ` [PATCH v4 0/2] xfstest " Eric Sandeen
2013-08-13 18:33 ` Eric Sandeen
2013-08-13 22:31 ` Rich Johnston
2013-08-13 22:31 ` Rich Johnston
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.