From: Andreas Dilger Date: Fri, 13 Apr 2012 18:55:45 +0000 (-0600) Subject: debugfs: decode and dump xattrs on inode stat X-Git-Tag: v1.47.1-wc1~20 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=4c054aaae2cb9fe0ab77dc0b9c74eaecfc5b6547;p=tools%2Fe2fsprogs.git 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 --- 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 0000000..9447f6f Binary files /dev/null and b/tests/d_trusted_fid/image.gz differ diff --git a/tests/d_trusted_fid/name b/tests/d_trusted_fid/name new file mode 100644 index 0000000..bb7f001 --- /dev/null +++ b/tests/d_trusted_fid/name @@ -0,0 +1 @@ +decode and print trusted.fid xattr in debugfs diff --git a/tests/d_trusted_fid/script b/tests/d_trusted_fid/script new file mode 100644 index 0000000..11ed9ad --- /dev/null +++ b/tests/d_trusted_fid/script @@ -0,0 +1,27 @@ +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 /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 0000000..b3b7e1c Binary files /dev/null and b/tests/d_trusted_link/image.gz differ 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 ""