From 4c054aaae2cb9fe0ab77dc0b9c74eaecfc5b6547 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Fri, 13 Apr 2012 12:55:45 -0600 Subject: [PATCH] debugfs: decode and dump xattrs on inode stat Decode and print Access Control Lists in debugfs stat/ea_list. Print the Lustre "fid", "lma", and "link" xattr contents, if present, with "debugfs stat" to simplify debugging. Add "layout_version" and "range" values when printing a trusted.fid xattr. Increase the size of xattrs hex-dumped from 40 to 120. But as Lustre encrypted inodes may contain illegal characters in their names, it is also needed to escape non-printable characters in linkEA. Change-Id: I3ee35ddb02582ab66d4e25ff76fae35935b54508 Reviewed-on: https://review.whamcloud.com/43384 Reviewed-by: Li Dongyang Reviewed-by: Andreas Dilger --- debugfs/Makefile.in | 1 + debugfs/debugfs.8.in | 16 ++- debugfs/debugfs.h | 1 + debugfs/xattrs.c | 284 +++++++++++++++++++++++++++++++++++++++++- lib/ext2fs/ext2fs.h | 3 +- lib/ext2fs/ext4_acl.h | 6 + lib/ext2fs/ext_attr.c | 6 +- lib/ext2fs/lfsck.h | 83 ++++++++++++ misc/fuse2fs.c | 5 +- tests/d_print_acl/expect | 13 ++ tests/d_print_acl/script | 55 ++++++++ tests/d_trusted_fid/expect | 4 + tests/d_trusted_fid/image.gz | Bin 0 -> 8361 bytes tests/d_trusted_fid/name | 1 + tests/d_trusted_fid/script | 27 ++++ tests/d_trusted_link/expect | 12 ++ tests/d_trusted_link/image.gz | Bin 0 -> 10740 bytes tests/d_trusted_link/name | 1 + tests/d_trusted_link/script | 26 ++++ tests/d_xattr_edits/expect | 2 +- tests/m_rootdir_acl/expect | 21 +++- tests/test_post | 3 +- 22 files changed, 555 insertions(+), 15 deletions(-) create mode 100644 tests/d_print_acl/expect create mode 100644 tests/d_print_acl/script create mode 100644 tests/d_trusted_fid/expect create mode 100644 tests/d_trusted_fid/image.gz create mode 100644 tests/d_trusted_fid/name create mode 100644 tests/d_trusted_fid/script create mode 100644 tests/d_trusted_link/expect create mode 100644 tests/d_trusted_link/image.gz create mode 100644 tests/d_trusted_link/name create mode 100644 tests/d_trusted_link/script diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in index 50a21e5..8bd62f5 100644 --- a/debugfs/Makefile.in +++ b/debugfs/Makefile.in @@ -53,6 +53,7 @@ STATIC_DEPLIBS= $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBSS) \ # clean up this mess, we should be able to drop it LOCAL_CFLAGS = -I$(srcdir)/../e2fsck -DDEBUGFS DEPEND_CFLAGS = -I$(srcdir) +@LFSCK_CMT@LUSTRE_INC=-I @LUSTRE@/lustre/include -I @LUSTRE@/include -I @LUSTRE@/libcfs/include -Wall .c.o: $(E) " CC $<" diff --git a/debugfs/debugfs.8.in b/debugfs/debugfs.8.in index 1225f88..68c363b 100644 --- a/debugfs/debugfs.8.in +++ b/debugfs/debugfs.8.in @@ -316,19 +316,29 @@ corruption in the file system.) .B dump_unused Dump unused blocks which contain non-null bytes. .TP -.BI ea_get " [-f outfile]|[-xVC] [-r] filespec attr_name" +.BI "ea_get [-f " outfile "]|[-xVC] [-r]" " filespec attr_name" Retrieve the value of the extended attribute .I attr_name in the file .I filespec -and write it either to stdout or to \fIoutfile\fR. +and write it either to stdout or to \fIoutfile\fR if +.B -f +is specified. If +.B -C +is used the xattr is printed with C-format escapes, and if +.B -x +is used the xattr is printed in hex format, while the +.B -V +option prints in raw format without quotes. The +.B -r +option prints the xattr name in raw format. .TP .BI ea_list " filespec List the extended attributes associated with the file .I filespec to standard output. .TP -.BI ea_set " [-f infile] [-r] filespec attr_name attr_value +.BI "ea_set [-f " infile "] [-r] " "filespec attr_name attr_value" Set the value of the extended attribute .I attr_name in the file diff --git a/debugfs/debugfs.h b/debugfs/debugfs.h index 88d929c..fffb08c 100644 --- a/debugfs/debugfs.h +++ b/debugfs/debugfs.h @@ -27,6 +27,7 @@ extern quota_ctx_t current_qctx; extern ext2_ino_t root, cwd; extern int ss_sci_idx; extern ss_request_table debug_cmds, extent_cmds; +extern const char *debug_prog_name; extern void reset_getopt(void); extern FILE *open_pager(void); diff --git a/debugfs/xattrs.c b/debugfs/xattrs.c index b518941..79665c7 100644 --- a/debugfs/xattrs.c +++ b/debugfs/xattrs.c @@ -17,6 +17,8 @@ extern char *optarg; #include "support/cstring.h" #include "debugfs.h" +#include "ext2fs/ext4_acl.h" +#include "ext2fs/lfsck.h" #define PRINT_XATTR_HEX 0x01 #define PRINT_XATTR_RAW 0x02 @@ -24,6 +26,8 @@ extern char *optarg; #define PRINT_XATTR_STATFMT 0x08 #define PRINT_XATTR_NOQUOTES 0x10 +extern const char *debug_prog_name; + /* Dump extended attributes */ static void print_xattr_hex(FILE *f, const char *str, int len) { @@ -74,19 +78,293 @@ static void print_xattr(FILE *f, char *name, char *value, size_t value_len, (strcmp(name, "system.data") == 0)) value_len = 0; if (value_len != 0 && - (!(print_flags & PRINT_XATTR_STATFMT) || (value_len < 40))) { + (!(print_flags & PRINT_XATTR_STATFMT) || (value_len < 120))) { fprintf(f, " = "); print_xattr_string(f, value, value_len, print_flags); } fputc('\n', f); } -static int dump_attr(char *name, char *value, size_t value_len, void *data) +static int print_acl(FILE *f, char *name, void *value, size_t value_len) +{ + const ext4_acl_header *ext_acl = (const ext4_acl_header *)value; + const char *cp; + + if (!value || + (value_len < sizeof(ext4_acl_header)) || + (ext_acl->a_version != ext2fs_cpu_to_le32(EXT4_ACL_VERSION))) + return -EINVAL; + + cp = (const char *)value + sizeof(ext4_acl_header); + value_len -= sizeof(ext4_acl_header); + + fprintf(f, "%s:\n", name); + + while (value_len > 0) { + const ext4_acl_entry *disk_entry = (const ext4_acl_entry *)cp; + posix_acl_xattr_entry entry; + entry.e_tag = ext2fs_le16_to_cpu(disk_entry->e_tag); + entry.e_perm = ext2fs_le16_to_cpu(disk_entry->e_perm); + + switch(entry.e_tag) { + case ACL_USER_OBJ: + case ACL_USER: + fprintf(f, " user:"); + if (entry.e_tag == ACL_USER) + fprintf(f, "%u", + ext2fs_le32_to_cpu(disk_entry->e_id)); + break; + + case ACL_GROUP_OBJ: + case ACL_GROUP: + fprintf(f, " group:"); + if (entry.e_tag == ACL_GROUP) + fprintf(f, "%u", + ext2fs_le32_to_cpu(disk_entry->e_id)); + break; + + case ACL_MASK: + fprintf(f, " mask:"); + break; + + case ACL_OTHER: + fprintf(f, " other:"); + break; + + default: + fprintf(stderr, + "%s: error: invalid tag %x in ACL\n", + debug_prog_name, entry.e_tag); + return -EINVAL; + } + fprintf(f, ":"); + fprintf(f, (entry.e_perm & ACL_READ) ? "r" : "-"); + fprintf(f, (entry.e_perm & ACL_WRITE) ? "w" : "-"); + fprintf(f, (entry.e_perm & ACL_EXECUTE) ? "x" : "-"); + fprintf(f, "\n"); + + if (entry.e_tag == ACL_USER || entry.e_tag == ACL_GROUP) { + cp += sizeof(ext4_acl_entry); + value_len -= sizeof(ext4_acl_entry); + } else { + cp += sizeof(ext4_acl_entry_short); + value_len -= sizeof(ext4_acl_entry_short); + } + } + + return 0; +} + +static int print_fidstr(FILE *f, char *name, void *value, size_t value_len) +{ + struct filter_fid_old *ff = value; + int stripe; + + /* Since Lustre 2.4 only the parent FID is stored in filter_fid, + * and the self fid is stored in the LMA and is printed below. */ + if (value_len < sizeof(ff->ff_parent)) { + fprintf(stderr, "%s: error: xattr '%s' too small (%zu bytes)\n", + debug_prog_name, name, value_len); + return -EINVAL; + } + fid_le_to_cpu(&ff->ff_parent, &ff->ff_parent); + stripe = fid_ver(&ff->ff_parent); /* stripe index is stored in f_ver */ + ff->ff_parent.f_ver = 0; + + fprintf(f, "fid: "); + /* Old larger filter_fid should only ever be used with seq = 0. + * FID-on-OST should use LMA for FID_SEQ_NORMAL OST objects. */ + if (value_len == sizeof(*ff)) + fprintf(f, "objid=%llu seq=%llu ", + ext2fs_le64_to_cpu(ff->ff_objid), + ext2fs_le64_to_cpu(ff->ff_seq)); + + fprintf(f, "parent="DFID" stripe=%u", PFID(&ff->ff_parent), stripe); + if (value_len >= sizeof(struct filter_fid_210)) { + struct filter_fid_210 *ff_new = value; + + fprintf(f, " stripe_size=%u stripe_count=%u", + ext2fs_le32_to_cpu(ff_new->ff_stripe_size), + ext2fs_le32_to_cpu(ff_new->ff_stripe_count)); + if (ff_new->ff_pfl_id != 0) + fprintf(f, " component_id=%u component_start=%llu " + "component_end=%llu", + ext2fs_le32_to_cpu(ff_new->ff_pfl_id), + ext2fs_le64_to_cpu(ff_new->ff_pfl_start), + ext2fs_le64_to_cpu(ff_new->ff_pfl_end)); + } + + if (value_len >= sizeof(struct filter_fid)) { + struct filter_fid *ff_new = value; + + fprintf(f, " layout_version=%u range=%u", + ext2fs_le32_to_cpu(ff_new->ff_layout_version), + ext2fs_le32_to_cpu(ff_new->ff_range)); + } + + fprintf(f, "\n"); + + return 0; +} + +static int print_lmastr(FILE *f, char *name, void *value, size_t value_len) +{ + struct lustre_mdt_attrs *lma = value; + struct lustre_ost_attrs *loa = value; + + if (value_len < offsetof(typeof(*lma), lma_self_fid) + + sizeof(lma->lma_self_fid)) { + fprintf(stderr, "%s: error: xattr '%s' too small (%zu bytes)\n", + debug_prog_name, name, value_len); + return -EINVAL; + } + fid_le_to_cpu(&lma->lma_self_fid, &lma->lma_self_fid); + fprintf(f, "lma: fid="DFID" compat=%x incompat=%x\n", + PFID(&lma->lma_self_fid), ext2fs_le32_to_cpu(lma->lma_compat), + ext2fs_le32_to_cpu(lma->lma_incompat)); + if (value_len >= offsetof(typeof(*loa), loa_pfl_end) + + sizeof(loa->loa_pfl_end)) { + int idx; + int cnt; + + fid_le_to_cpu(&loa->loa_parent_fid, &loa->loa_parent_fid); + idx = loa->loa_parent_fid.f_ver & PFID_STRIPE_COUNT_MASK; + cnt = loa->loa_parent_fid.f_ver >> PFID_STRIPE_IDX_BITS; + loa->loa_parent_fid.f_ver = 0; + + fprintf(f, " fid: parent="DFID" stripe=%u stripe_size=%u " + "stripe_count=%u", PFID(&loa->loa_parent_fid), idx, + ext2fs_le32_to_cpu(loa->loa_stripe_size), cnt); + if (loa->loa_pfl_id != 0) + fprintf(f, " component_id=%u component_start=%llu " + "component_end=%llu", + ext2fs_le32_to_cpu(loa->loa_pfl_id), + ext2fs_le64_to_cpu(loa->loa_pfl_start), + ext2fs_le64_to_cpu(loa->loa_pfl_end)); + fprintf(f, "\n"); + } + + return 0; +} + +static void print_name(FILE *f, const char *cp, int len) +{ + unsigned char ch; + + while (len--) { + ch = *cp++; + if (!isprint(ch) || ch == '\\') { + if (f) + fprintf(f, "\\x%02x", ch); + } else { + if (f) + fputc(ch, f); + } + } +} + +static int print_linkea(FILE *f, char *name, void *value, size_t value_len) { + struct link_ea_header *leh = value; + struct link_ea_entry *lee; + int i; + + if (value_len < sizeof(*leh) || + value_len < ext2fs_le64_to_cpu(leh->leh_len)) { + fprintf(stderr, "%s: error: xattr '%s' too small (%zu bytes)\n", + debug_prog_name, name, value_len); + return -EINVAL; + } + + if (ext2fs_le32_to_cpu(leh->leh_magic) != LINK_EA_MAGIC) { + fprintf(stderr, "%s: error: xattr '%s' bad magic '%#x'\n", + debug_prog_name, name, + ext2fs_le32_to_cpu(leh->leh_magic)); + return -EINVAL; + } + + lee = leh->leh_entry; + value_len -= sizeof(*leh); + + for (i = 0; i < ext2fs_le32_to_cpu(leh->leh_reccount) && + value_len > 2; i++) { + int reclen = lee->lee_reclen[0] << 8 | lee->lee_reclen[1]; + struct lu_fid pfid; + + if (value_len < sizeof(*lee) || value_len < reclen) { + fprintf(stderr, + "%s: error: xattr '%s' entry %d too small " + "(%zu bytes)\n", + debug_prog_name, name, i, value_len); + return -EINVAL; + } + + memcpy(&pfid, &lee->lee_parent_fid, sizeof(pfid)); + fid_be_to_cpu(&pfid, &pfid); + fprintf(f, "%s idx=%u parent="DFID" name='", + i == 0 ? "linkea:" : " ", i, PFID(&pfid)); + print_name(f, lee->lee_name, reclen - (int)sizeof(*lee)); + fprintf(f, "'\n"); + + lee = (struct link_ea_entry *)((char *)lee + reclen); + value_len -= reclen; + } + + return 0; +} + +struct dump_attr_pretty { + const char *dap_name; + int (*dap_print)(FILE *f, char *name, void *value, size_t value_len); +} dumpers[] = { + { + .dap_name = "system.posix_acl_access", + .dap_print = print_acl, + }, + { + .dap_name = "system.posix_acl_default", + .dap_print = print_acl, + }, + { + .dap_name = "trusted.fid", + .dap_print = print_fidstr, + }, + { + .dap_name = "trusted.lma", + .dap_print = print_lmastr, + }, + { + .dap_name = "trusted.link", + .dap_print = print_linkea, + }, + { + .dap_name = NULL, + } +}; + +static int dump_attr(char *name, char *value, size_t value_len, + ext2_ino_t inode_num, void *data) +{ + struct dump_attr_pretty *dap; FILE *out = data; + int rc = 0; fprintf(out, " "); - print_xattr(out, name, value, value_len, PRINT_XATTR_STATFMT); + if (EXT2_HAS_INCOMPAT_FEATURE(current_fs->super, + EXT4_FEATURE_INCOMPAT_EA_INODE) && + inode_num != 0) { + fprintf(out, "inode <%u> ", inode_num); + } + + for (dap = dumpers; dap->dap_name != NULL; dap++) { + if (strcmp(name, dap->dap_name) == 0) { + rc = dap->dap_print(out, name, value, value_len); + break; + } + } + if (dap->dap_name == NULL || rc) + print_xattr(out, name, value, value_len, PRINT_XATTR_STATFMT); + return 0; } diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index 1a7e00c..de2b4db 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -1408,7 +1408,8 @@ errcode_t ext2fs_xattrs_read_inode(struct ext2_xattr_handle *handle, struct ext2_inode_large *inode); errcode_t ext2fs_xattrs_iterate(struct ext2_xattr_handle *h, int (*func)(char *name, char *value, - size_t value_len, void *data), + size_t value_len, + ext2_ino_t inode_num, void *data), void *data); errcode_t ext2fs_xattr_get(struct ext2_xattr_handle *h, const char *key, void **value, size_t *value_len); diff --git a/lib/ext2fs/ext4_acl.h b/lib/ext2fs/ext4_acl.h index 8d4d974..8343086 100644 --- a/lib/ext2fs/ext4_acl.h +++ b/lib/ext2fs/ext4_acl.h @@ -4,6 +4,12 @@ #define EXT4_ACL_VERSION 0x0001 +/* 23.2.2 acl_perm_t values */ + +#define ACL_READ (0x04) +#define ACL_WRITE (0x02) +#define ACL_EXECUTE (0x01) + /* 23.2.5 acl_tag_t values */ #define ACL_UNDEFINED_TAG (0x00) diff --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c index cdce884..aaf2d6b 100644 --- a/lib/ext2fs/ext_attr.c +++ b/lib/ext2fs/ext_attr.c @@ -432,6 +432,7 @@ static struct ea_name_index ea_names[] = { {2, "system.posix_acl_access"}, {8, "system.richacl"}, {6, "security."}, + {5, "lustre."}, {4, "trusted."}, {7, "system."}, {1, "user."}, @@ -1195,7 +1196,8 @@ out: errcode_t ext2fs_xattrs_iterate(struct ext2_xattr_handle *h, int (*func)(char *name, char *value, - size_t value_len, void *data), + size_t value_len, + ext2_ino_t inode_num, void *data), void *data) { struct ext2_xattr *x; @@ -1204,7 +1206,7 @@ errcode_t ext2fs_xattrs_iterate(struct ext2_xattr_handle *h, EXT2_CHECK_MAGIC(h, EXT2_ET_MAGIC_EA_HANDLE); for (x = h->attrs; x < h->attrs + h->count; x++) { - ret = func(x->name, x->value, x->value_len, data); + ret = func(x->name, x->value, x->value_len, x->ea_ino, data); if (ret & XATTR_CHANGED) dirty = 1; if (ret & XATTR_ABORT) diff --git a/lib/ext2fs/lfsck.h b/lib/ext2fs/lfsck.h index 6a49042..5f182bc 100644 --- a/lib/ext2fs/lfsck.h +++ b/lib/ext2fs/lfsck.h @@ -34,6 +34,89 @@ static inline void fid_be_to_cpu(struct lu_fid *dst, struct lu_fid *src) dst->f_oid = ext2fs_be32_to_cpu(src->f_oid); dst->f_ver = ext2fs_be32_to_cpu(src->f_ver); } + +static inline void fid_le_to_cpu(struct lu_fid *dst, struct lu_fid *src) +{ + dst->f_seq = ext2fs_le64_to_cpu(src->f_seq); + dst->f_oid = ext2fs_le32_to_cpu(src->f_oid); + dst->f_ver = ext2fs_le32_to_cpu(src->f_ver); +} +#endif /* HAVE_LUSTRE_LUSTRE_IDL_H */ + +#define LUSTRE_XATTR_MDT_LOV "lov" +#define LUSTRE_XATTR_MDT_LMA "lma" +#define LUSTRE_XATTR_MDT_LINK "link" +#define LUSTRE_XATTR_OST_FID "fid" + +#ifndef LMA_OLD_SIZE +#ifndef LMA_INCOMPAT_SUPP +struct lustre_mdt_attrs { + __u32 lma_compat; + __u32 lma_incompat; + struct lu_fid lma_self_fid; +}; +struct lustre_ost_attrs { + struct lustre_mdt_attrs loa_lma; + struct lu_fid loa_parent_fid; + __u32 loa_stripe_size; + __u32 loa_pfl_id; + __u64 loa_pfl_start; + __u64 loa_pfl_end; +}; +#endif + +struct filter_fid_old { + struct lu_fid ff_parent; + __u64 ff_objid; + __u64 ff_seq; +}; + +struct filter_fid_210 { + struct lu_fid ff_parent; + __u32 ff_stripe_size; + __u32 ff_stripe_count; + __u64 ff_pfl_start; + __u64 ff_pfl_end; + __u32 ff_pfl_id; +}; + +struct filter_fid { + struct lu_fid ff_parent; + __u32 ff_stripe_size; + __u32 ff_stripe_count; + __u64 ff_pfl_start; + __u64 ff_pfl_end; + __u32 ff_pfl_id; + __u32 ff_layout_version; + __u32 ff_range; +} __attribute__((packed)); + +#define LMA_OLD_SIZE 64 +#endif /* !LMA_OLD_SIZE */ + +#define PFID_STRIPE_IDX_BITS 16 +#define PFID_STRIPE_COUNT_MASK ((1 << PFID_STRIPE_IDX_BITS) - 1) + +#ifndef LINK_EA_MAGIC +/** Hardlink data is name and parent fid. + * Stored in this crazy struct for maximum packing and endian-neutrality */ +struct link_ea_entry { + /** lee_reclen is a __u16 stored big-endian, unaligned */ + unsigned char lee_reclen[2]; /* record size in bytes */ + unsigned char lee_parent_fid[sizeof(struct lu_fid)]; + char lee_name[0]; /* filename without trailing NUL */ +}__attribute__((packed)); + +/** The link ea holds 1 \a link_ea_entry for each hardlink */ +#define LINK_EA_MAGIC 0x11EAF1DFUL +struct link_ea_header { + __u32 leh_magic; /* LINK_EA_MAGIC */ + __u32 leh_reccount; /* number of records in leh_entry[] */ + __u64 leh_len; /* total size in bytes */ + __u32 leh_overflow_time; /* when link xattr ran out of space */ + __u32 padding; + struct link_ea_entry leh_entry[0]; /* packed array of variable-size entries */ +}; #endif #endif /* LFSCK_H */ diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index 56a0d54..177cd70 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -2525,6 +2525,7 @@ out: static int count_buffer_space(char *name, char *value EXT2FS_ATTR((unused)), size_t value_len EXT2FS_ATTR((unused)), + ext2_ino_t inode_num EXT2FS_ATTR((unused)), void *data) { unsigned int *x = data; @@ -2534,7 +2535,9 @@ static int count_buffer_space(char *name, char *value EXT2FS_ATTR((unused)), } static int copy_names(char *name, char *value EXT2FS_ATTR((unused)), - size_t value_len EXT2FS_ATTR((unused)), void *data) + size_t value_len EXT2FS_ATTR((unused)), + ext2_ino_t inode_num EXT2FS_ATTR((unused)), + void *data) { char **b = data; size_t name_len = strlen(name); diff --git a/tests/d_print_acl/expect b/tests/d_print_acl/expect new file mode 100644 index 0000000..03dea43 --- /dev/null +++ b/tests/d_print_acl/expect @@ -0,0 +1,13 @@ +Extended attributes: + system.posix_acl_access: + user::rwx + group::r-x + group:42:r-x + mask::r-x + other::r-x + system.posix_acl_default: + user::rwx + group::r-x + group:4:r-x + mask::r-x + other::r-x diff --git a/tests/d_print_acl/script b/tests/d_print_acl/script new file mode 100644 index 0000000..d5cbd62 --- /dev/null +++ b/tests/d_print_acl/script @@ -0,0 +1,55 @@ +test_description="decode and print Access Control Lists in debugfs" +if ! test -x $DEBUGFS_EXE; then + echo "$test_name: $test_description: skipped (no debugfs)" + return 0 +fi + +if ! setfacl --help > /dev/null 2>&1 ; then + echo "$test_name: $test_description: skipped (no setfacl)" + return 0 +fi + +MKFS_DIR=$(mktemp -d ./$test_name-XXXXXX.tmp) +OUT=$test_name.log +EXP=$test_dir/expect + +mkdir $MKFS_DIR/acl_dir + +setfacl --restore=- < $OUT.new 2>&1 + +$DEBUGFS -w -R "ea_list /acl_dir" $TMPFILE >> $OUT.new 2>&1 +sed -f $cmd_dir/filter.sed $OUT.new > $OUT +rm -rf $MKFS_DIR $TMPFILE $OUT.new + +cmp -s $OUT $EXP +status=$? + +if [ "$status" = 0 ] ; then + echo "$test_name: $test_description: ok" + touch $test_name.ok +else + echo "$test_name: $test_description: failed" + diff $DIFF_OPTS $EXP $OUT > $test_name.failed +fi + +unset MKFS_DIR OUT EXP diff --git a/tests/d_trusted_fid/expect b/tests/d_trusted_fid/expect new file mode 100644 index 0000000..e601771 --- /dev/null +++ b/tests/d_trusted_fid/expect @@ -0,0 +1,4 @@ +Extended attributes: + fid: parent=[0x200000402:0xc:0x0] stripe=1 stripe_size=1048576 stripe_count=2 layout_version=0 range=0 +Extended attributes: + fid: parent=[0x200000402:0x8:0x0] stripe=1 stripe_size=1048576 stripe_count=2 component_id=65537 component_start=0 component_end=18446744073709551615 layout_version=6 range=0 diff --git a/tests/d_trusted_fid/image.gz b/tests/d_trusted_fid/image.gz new file mode 100644 index 0000000000000000000000000000000000000000..9447f6fcd363d128c35eeb5b4a64fe04f3b85b3e GIT binary patch literal 8361 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 $TMPFILE + +$DEBUGFS -w -R "ea_list /plain" $TMPFILE >> $OUT.new 2>&1 +$DEBUGFS -w -R "ea_list /pfl_flr" $TMPFILE >> $OUT.new 2>&1 +sed -f $cmd_dir/filter.sed $OUT.new > $OUT +rm -f $TMPFILE $OUT.new + +cmp -s $OUT $EXP +status=$? + +if [ "$status" = 0 ] ; then + echo "$test_name: $test_description: ok" + touch $test_name.ok +else + echo "$test_name: $test_description: failed" + diff $DIFF_OPTS $EXP $OUT > $test_name.failed +fi + +unset IMAGE EXP OUT diff --git a/tests/d_trusted_link/expect b/tests/d_trusted_link/expect new file mode 100644 index 0000000..5c2bbda --- /dev/null +++ b/tests/d_trusted_link/expect @@ -0,0 +1,12 @@ +Extended attributes: + linkea: idx=0 parent=[0x200000007:0x1:0x0] name='file' + idx=1 parent=[0x240000404:0x1:0x0] name='file-link-1' + idx=2 parent=[0x240000404:0x1:0x0] name='file-link-2' + idx=3 parent=[0x240000404:0x1:0x0] name='file-link-3' + idx=4 parent=[0x240000404:0x1:0x0] name='file-link-4' + idx=5 parent=[0x240000404:0x1:0x0] name='file-link-5' + idx=6 parent=[0x240000404:0x1:0x0] name='file-link-6' + idx=7 parent=[0x240000404:0x1:0x0] name='file-link-7' + idx=8 parent=[0x240000404:0x1:0x0] name='file-link-8' + idx=9 parent=[0x240000404:0x1:0x0] name='file-link-9' + idx=10 parent=[0x240000404:0x1:0x0] name='file-link-10' diff --git a/tests/d_trusted_link/image.gz b/tests/d_trusted_link/image.gz new file mode 100644 index 0000000000000000000000000000000000000000..b3b7e1ce67ff4b4177e581d5574f71625b4173eb GIT binary patch literal 10740 zcmeI!ZB!Fi8USEcENBsEx2;wb*{&{}u8SX~K?DJ7TR2FOkAwh$BnS#P10uyyi3V+H z#V)0+TEC_nJ~iZPGJH57i3z1ts8Udt%uEfEs0h@FC>1B_NRn;;^zg&ebNbudANSlp z_nz}U?|a|#`c=%E7vOOybB^ndf~~pRUG9zKe!Xq`Cx>pq)o)Gwx7h7++Q#=Tub)^k zXY(tZjjzAz_WEn}M{4h^nDg@Hg#XlTb6x+>#AEX|zj7_{6^>Q%#sZH4O)k#&x?0R2 z3cWd;&wp%sptQ3a-Cb{bf~ozXZ!R6Ooe5gt)*vuF%5Bx(=v&gexbTj(tSfeP!J|h_ zjvKqbofX!OfwIG7Onbqe0SH8%d|wo#KJe3c!&g5&6i#R5l;9_e9MmtZ z0V5i7wpK0vq0YT#!-HEXktLU!N^i{S`VA@#Ura}OVQQC$~9$w$+kgSYCBP%WvOwhZh zt-ro_j*H*`&1)c37%<6eBoG>~Il886_FSvE@8`Ssjum}$<*6SNpdaXu3L*bE8pn}A zN4Ds@uBN)r?KAuG^6K(A+@I7+qB)M&CgwpZEvgf7bkB_a35 z1Y>81gTp2?827;K3yV`C@~0D{^PfJpy3PvJUeczVwD@B0>st4y1|2tZCqyYa?H)NF zY&Ysm?EQvn+9VR{I;{#FSi@|bO!rfHfpDxPKUOAr5v?<7TUZ;aoqBCD5lS7#8aq8 zp$!8nlprZps8%m9%ZjNRq38fwNVHR*YMS)?MffEshR-w09}wH25`JO|kqkk6wpsar z^rp(80)7ffdP3PFoONU%1dedqNng5wDH=)Ji;qC@Bk7Ovc*-uSU8X9hZZSK;lOmPT zmS(2JR=*4lpe~CPrD^eG5S?#Rl=2&>b@Z@EU5%P?4?4@Hwot4`c?|74yADO>qU+=ZdrtV$6b4+=r!5MR%DJ_iHf)(qOCcf67#?mJR59Hy% zRZ*c1H3|3QCM;fDYel??a-fshH7WFyyHel!q`Bi=^dOV!o8*Va8v-nB`flj?2zEK1 zYbl2IiS=K}RvV5&9C5Rr6HTs#@_kc!$@x&0gcCr%4FTegElSjI7mAXk2@w=egZ7AZ z`osxC2PBXP&8kBDC1|TyyGl`EIi@+UXPc2e>Y=7ytx{5yMygLSqkaZ&i&3Liqf4kB zjeMs%ogy^IPBe^)rbjic_Z3=8wWj^Pvc_PeH-@Kr^jE4w7 z1B`JIzQv%y1c-2n;V_n1knxQ{ilr3@(hVoE$+}A zuu$HX(rhNVpMpBdZ%Gm|NnS(V!mshCHQ9e zAyxQW^e@Z@;+BZy8uj~@AShMb7Lig;PFRjGn|#xv@kN$cXtyuBmneb`ND=~w80ce3 zQX_H7a-P{N5#$=q&^W`BB{VG09YejVem6`OTs^}!o z!`^P)z^`M_5g%obx(K-8gZ7~Ff$w0Mzd8o^AFT36-v+M03aNSrV1(6DbTQBa%X8Fe z00AR8=z3rPR*tJn027Rkqc2f$SY{x{gZw*|7s#z3|B7u3OpYbr!SZz-CzWI1=b~60 z##No53TP{@gDX!4F`kZ)u|R~UCFBsO<8=nhJi*x`RUoJ|YTD!lpw_52t-Zmxzjzfq zE8>gBuySuVXIFlHSI+!CbB*dSu&+|q4BYc+>_L73X5d87?cybfB5Iq5&;9*=P4p#D72?Yj9cyw|+FYGi4Uef5T^d!xtWrXFHX)=8I%7n31q z#t&f+TApnwI}=sNZ(jKXZC@3_%n|GwTQ(>% literal 0 HcmV?d00001 diff --git a/tests/d_trusted_link/name b/tests/d_trusted_link/name new file mode 100644 index 0000000..d776f73 --- /dev/null +++ b/tests/d_trusted_link/name @@ -0,0 +1 @@ +decode and print trusted.link xattr in debugfs diff --git a/tests/d_trusted_link/script b/tests/d_trusted_link/script new file mode 100644 index 0000000..0d93015 --- /dev/null +++ b/tests/d_trusted_link/script @@ -0,0 +1,26 @@ +if ! test -x $DEBUGFS_EXE; then + echo "$test_name: $test_description: skipped (no debugfs)" + return 0 +fi + +IMAGE=$test_dir/image.gz +EXP=$test_dir/expect +OUT=$test_name.log +gunzip < $IMAGE > $TMPFILE + +$DEBUGFS -w -R "ea_list /file" $TMPFILE >> $OUT.new 2>&1 +sed -f $cmd_dir/filter.sed $OUT.new > $OUT +rm -f $TMPFILE $OUT.new + +cmp -s $OUT $EXP +status=$? + +if [ "$status" = 0 ] ; then + echo "$test_name: $test_description: ok" + touch $test_name.ok +else + echo "$test_name: $test_description: failed" + diff $DIFF_OPTS $EXP $OUT > $test_name.failed +fi + +unset IMAGE EXP OUT diff --git a/tests/d_xattr_edits/expect b/tests/d_xattr_edits/expect index 6a4d912..b961946 100644 --- a/tests/d_xattr_edits/expect +++ b/tests/d_xattr_edits/expect @@ -36,7 +36,7 @@ ea_set -f d_xattr_edits.tmp / user.file_based_xattr Exit status is 0 ea_list / Extended attributes: - user.file_based_xattr (108) + user.file_based_xattr (108) = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567\n" Exit status is 0 ea_get / user.file_based_xattr user.file_based_xattr (108) = "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567\n" diff --git a/tests/m_rootdir_acl/expect b/tests/m_rootdir_acl/expect index d3a8101..1e41a84 100644 --- a/tests/m_rootdir_acl/expect +++ b/tests/m_rootdir_acl/expect @@ -105,12 +105,27 @@ Extended attributes: debugfs: ea_list acl_dir Extended attributes: system.data (0) - system.posix_acl_access (28) = 01 00 00 00 01 00 07 00 04 00 05 00 08 00 05 00 2a 00 00 00 10 00 05 00 20 00 05 00 - system.posix_acl_default (28) = 01 00 00 00 01 00 07 00 04 00 05 00 08 00 05 00 04 00 00 00 10 00 05 00 20 00 05 00 + system.posix_acl_access: + user::rwx + group::r-x + group:42:r-x + mask::r-x + other::r-x + system.posix_acl_default: + user::rwx + group::r-x + group:4:r-x + mask::r-x + other::r-x debugfs: ea_list acl_dir/file Extended attributes: system.data (0) - system.posix_acl_access (28) = 01 00 00 00 01 00 07 00 04 00 05 00 08 00 05 00 2a 00 00 00 10 00 05 00 20 00 05 00 + system.posix_acl_access: + user::rwx + group::r-x + group:42:r-x + mask::r-x + other::r-x Pass 1: Checking inodes, blocks, and sizes Pass 2: Checking directory structure Pass 3: Checking directory connectivity diff --git a/tests/test_post b/tests/test_post index 1251266..c9acffb 100755 --- a/tests/test_post +++ b/tests/test_post @@ -10,7 +10,8 @@ test "$num_failed" -eq 0 && exit 0 echo -n "Tests failed: " for fname in $(ls *.failed); do - echo -n "${fname%%.failed} " + echo "${fname%%.failed} " + cat $fname done echo "" -- 1.8.3.1