From: Alexandre Ioffe Date: Wed, 6 Sep 2023 08:17:59 +0000 (-0700) Subject: EX-7290 lipe: lipe_find3 get attr warnings X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=a3b5298134b921362d624d934f0653719f273f40;p=fs%2Flustre-release.git EX-7290 lipe: lipe_find3 get attr warnings Report each get attr error when command line option --warnings=get-attr. Count all get attr errors per attr type and report them at the end. Exclude the 'trusted.link' when scanning an OST. Test-Parameters: trivial testlist=sanity-lipe-scan3,sanity-lipe-find3,sanityn Signed-off-by: Alexandre Ioffe Change-Id: I5e9b226bd4046eddcf779ca06af0892589d447ac Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/52292 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger --- diff --git a/lipe/man/lipe_find3.1 b/lipe/man/lipe_find3.1 index 74c9a2a..2909e66 100644 --- a/lipe/man/lipe_find3.1 +++ b/lipe/man/lipe_find3.1 @@ -31,6 +31,9 @@ list available JSON attribute names and exit \fB\-\-thread\-count\fR=\fICOUNT\fR use COUNT scaninng threads (default 4) .TP +\fB\-\-warnings\fR=\fIWARN_TYPE\fR +enable additional warning diagnostic. Available warning type: get-attr - warning is reported when getting file attribute fails +.TP \fB\-h\fR, \fB\-\-help\fR display this help text and exit .TP diff --git a/lipe/src/lipe_find3/lf3_parse.y b/lipe/src/lipe_find3/lf3_parse.y index 0aee9d7..7e4fdc3 100644 --- a/lipe/src/lipe_find3/lf3_parse.y +++ b/lipe/src/lipe_find3/lf3_parse.y @@ -287,7 +287,9 @@ static char *lf3_user_expr(int begin, int end) if (rc == INT_MIN) LF3_FATAL_AT(begin + 1, "'%s' is not the name of a known user\n", name); else if (rc < 0) - LF3_FATAL_AT(begin + 1, "cannot get UID for user '%s': %s\n", name, strerror(-rc)); + LF3_FATAL_AT(begin + 1, + "cannot get UID for user '%s': %s\n", + name, strerror(-rc)); return xsprintf("(= (uid) %llu)", (__ull)id); } @@ -304,7 +306,9 @@ static char *lf3_group_expr(int begin, int end) if (rc == INT_MIN) LF3_FATAL_AT(begin + 1, "'%s' is not the name of a known group\n", name); else if (rc < 0) - LF3_FATAL_AT(begin + 1, "cannot get GID for group '%s': %s\n", name, strerror(-rc)); + LF3_FATAL_AT(begin + 1, + "cannot get GID for group '%s': %s\n", + name, strerror(-rc)); return xsprintf("(= (gid) %llu)", (__ull)id); } @@ -1312,6 +1316,7 @@ enum { LF3_OPT_NOW, LF3_OPT_SCAN_COMMAND, LF3_OPT_THREAD_COUNT, + LF3_OPT_WARN, LF3_OPT_HELP = 'h', LF3_OPT_VERSION = 'v', }; @@ -1329,6 +1334,7 @@ static void help(void) /* --now=EPOCH use EPOCH instead of current time (for testing) */ /* --scan-command=COMMAND use 'cat' to print the code we would send to lipe_scan3 */ " --thread-count=COUNT use COUNT scaninng threads\n" +" --warnings=get-attr enable get attribute warnings\n" " -h, --help display this help text and exit\n" " -v, --version output version information and exit\n", program_invocation_short_name); @@ -1341,6 +1347,7 @@ static const struct option options[] = { { "now", required_argument, 0, LF3_OPT_NOW }, { "scan-command", required_argument, 0, LF3_OPT_SCAN_COMMAND }, { "thread-count", required_argument, 0, LF3_OPT_THREAD_COUNT }, + { "warnings", required_argument, 0, LF3_OPT_WARN }, { "help", no_argument, 0, LF3_OPT_HELP }, { "version", no_argument, 0, LF3_OPT_VERSION }, { NULL }, @@ -1351,6 +1358,7 @@ int main(int argc, char *argv[]) const char *scan_command = LF3_SCAN_COMMAND; const char *thread_count = NULL; bool debug_scan = false; + const char *opt_warns = NULL; int rc; int c; @@ -1383,6 +1391,9 @@ int main(int argc, char *argv[]) case LF3_OPT_THREAD_COUNT: thread_count = optarg; break; + case LF3_OPT_WARN: + opt_warns = optarg; + break; case LF3_OPT_HELP: help(); exit(EXIT_SUCCESS); @@ -1406,6 +1417,20 @@ int main(int argc, char *argv[]) if (debug_scan) lf3_init_add("(lipe-debug-enable #t)"); + if (opt_warns) { + if (strcmp(opt_warns, "get-attr") == 0) + lf3_init_add("(lipe-warnings-get-attr-enable #t)"); + else { + fprintf(stderr, + "Usage: --warnings=get-attr\n" + "Try '%s --help for more information.\n", + program_invocation_short_name); + exit(EXIT_FAILURE + 1); + } + } + + LF3_DEBUG_S(opt_warns); + if (lf3_now == -1) lf3_now = time(NULL); diff --git a/lipe/src/lipe_scan3/lipe-scan3-notes.txt b/lipe/src/lipe_scan3/lipe-scan3-notes.txt index b64e767..ef464e4 100644 --- a/lipe/src/lipe_scan3/lipe-scan3-notes.txt +++ b/lipe/src/lipe_scan3/lipe-scan3-notes.txt @@ -161,6 +161,7 @@ Other procedures The following can be called from any context: (lipe-debug-enable [enable]) enable or disable debugging. Returns previous value. + (lipe-warnings-get-attr-enable [enable]) enable or disable warning report when get attr errored. Returns previous value. (lipe-gettid) return calling thread ID (Linux tid for gdb -p, not pthread ID) (lipe-getopt-client-mount-path) see above (lipe-getopt-required-attrs) see above diff --git a/lipe/src/lipe_scan3/ls3_debug.h b/lipe/src/lipe_scan3/ls3_debug.h index 926c687..fbbffde 100644 --- a/lipe/src/lipe_scan3/ls3_debug.h +++ b/lipe/src/lipe_scan3/ls3_debug.h @@ -21,6 +21,7 @@ enum { }; extern bool ls3_debug; +extern bool ls3_warn_get_attr; extern const char *ls3_progname_; extern __thread int ls3_tid; @@ -49,6 +50,14 @@ static inline const char *ls3_progname(void) #define LS3_WARNING(fmt, args...) \ fprintf(stderr, "%s[%d]: WARNING: "fmt, ls3_progname(), ls3_tid, ##args) +/* +#define LS3_WARN_GET_ATTR(fmt, args...) \ + do { \ + if (ls3_warn_get_attr) \ + LS3_WARNING(fmt, ##args) \ + } while (0) +*/ + #define LS3_ERROR_ONCE(fmt, args...) \ do { \ static int ls3_error_once; \ diff --git a/lipe/src/lipe_scan3/ls3_main.c b/lipe/src/lipe_scan3/ls3_main.c index bd58057..a304630 100644 --- a/lipe/src/lipe_scan3/ls3_main.c +++ b/lipe/src/lipe_scan3/ls3_main.c @@ -55,6 +55,7 @@ SCM ls3_scm_policy_exception_handler; bool ls3_debug; bool save_fsize_stats; +bool ls3_warn_get_attr; const char *ls3_progname_; __thread int ls3_tid; /* gettid() thread id for debug messages. */ @@ -416,6 +417,17 @@ SCM_DEFINE(ls3_scm_debug_enable, "lipe-debug-enable", 0, 1, 0, return scm_from_bool(old_debug); } +SCM_DEFINE(ls3_scm_warn_get_attr_enable, "lipe-warnings-get-attr-enable", 0, 1, 0, + (SCM enable), "get or set get attr warning") +{ + bool old_warn = ls3_warn_get_attr; + + if (!SCM_UNBNDP(enable)) + ls3_warn_get_attr = scm_is_true(enable); + + return scm_from_bool(old_warn); +} + SCM_DEFINE(ls3_scm_gettid, "lipe-gettid", 0, 0, 0, (), "print caller's thread ID (not pthread id)") { return scm_from_ulong(syscall(SYS_gettid)); @@ -534,6 +546,7 @@ static void ls3_throw_read_attr_error(enum ls3_object_attr_bit bits, { struct ls3_object_attrs *loa = ls3_current()->lc_attrs; + /* *** See ls3_policy_exception_handler */ scm_throw(ls3_sym_read_attr_error, scm_list_3(scm_from_ulong(loa->loa_ino), scm_from_ulong(bits), @@ -550,12 +563,10 @@ static struct ls3_object_attrs *ls3_attrs_try(enum ls3_object_attr_bit bits) if ((loa->loa_valid & bits) == bits) return loa; - ls3_read_attrs(ls3_current()->lc_instance, ls3_current()->lc_object, loa, bits, false /* quit_on_error */); - return loa; } @@ -1384,6 +1395,7 @@ static void ls3_module_init(void *unused) "lipe-getopt-device-path", "lipe-getopt-required-attrs", "lipe-getopt-thread-count", + "lipe-warnings-get-attr-enable", "lipe-scan", "lipe-scan-break", "lipe-scan-client-mount-fd", diff --git a/lipe/src/lipe_scan3/ls3_object_attrs.h b/lipe/src/lipe_scan3/ls3_object_attrs.h index 8edd54c..282f2f0 100644 --- a/lipe/src/lipe_scan3/ls3_object_attrs.h +++ b/lipe/src/lipe_scan3/ls3_object_attrs.h @@ -15,41 +15,107 @@ struct ls3_instance; struct lipe_object; struct json_object; +#define BIT(pos) (1U << (pos)) + +enum ls3_object_attr_bit_pos { + LS3_OBJECT_ATTR_BIT_BASE, + LS3_OBJECT_ATTR_BIT_PROJID, + LS3_OBJECT_ATTR_BIT_FILTER_FID, + LS3_OBJECT_ATTR_BIT_HSM, + LS3_OBJECT_ATTR_BIT_LINKS, + LS3_OBJECT_ATTR_BIT_LMV, + LS3_OBJECT_ATTR_BIT_LOV, + LS3_OBJECT_ATTR_BIT_SELF_FID, + LS3_OBJECT_ATTR_BIT_SOM, + LS3_OBJECT_ATTR_BIT_XATTRS, + LS3_OBJECT_ATTR_BIT_FILE_FID, + LS3_OBJECT_ATTR_BIT_SIZE, + LS3_OBJECT_ATTR_BIT_PATHS, + + LS3_OBJECT_ATTR_BIT_MAX +}; + +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof((a)[0]))) +#endif + +static inline const char *ls3_object_attr_bit_pos2str(enum ls3_object_attr_bit_pos pos) +{ + const char *attr_bit_str[LS3_OBJECT_ATTR_BIT_MAX] = { + [LS3_OBJECT_ATTR_BIT_BASE] = "base", + [LS3_OBJECT_ATTR_BIT_PROJID] = "projid", + [LS3_OBJECT_ATTR_BIT_FILTER_FID] = "filter_fid", + [LS3_OBJECT_ATTR_BIT_HSM] = "hsm", + [LS3_OBJECT_ATTR_BIT_LINKS] = "links", + [LS3_OBJECT_ATTR_BIT_LMV] = "lmv", + [LS3_OBJECT_ATTR_BIT_LOV] = "lov", + [LS3_OBJECT_ATTR_BIT_SELF_FID] = "self_fid", + [LS3_OBJECT_ATTR_BIT_SOM] = "som", + [LS3_OBJECT_ATTR_BIT_XATTRS] = "xattrs", + [LS3_OBJECT_ATTR_BIT_FILE_FID] = "file_fid", + [LS3_OBJECT_ATTR_BIT_SIZE] = "size", + [LS3_OBJECT_ATTR_BIT_PATHS] = "paths", + }; + if (pos >= ARRAY_SIZE(attr_bit_str)) + return ""; + return attr_bit_str[pos]; +} + enum ls3_object_attr_bit { /* Includes ino, mode, nlink, uid, gid, atime, ctime, mtime * and flags. Does not include size/blocks. */ - LS3_OBJECT_ATTR_BASE = 0x0001, - LS3_OBJECT_ATTR_PROJID = 0x0002, + LS3_OBJECT_ATTR_BASE = BIT(LS3_OBJECT_ATTR_BIT_BASE), + LS3_OBJECT_ATTR_PROJID = BIT(LS3_OBJECT_ATTR_BIT_PROJID), /* OST objects XATTR_NAME_FID which saves the prarent FID * (i.e. the FID of the file on MDT). Files on MDT don't have * this xattr. */ - LS3_OBJECT_ATTR_FILTER_FID = 0x0004, /* XATTR_NAME_FID */ - LS3_OBJECT_ATTR_HSM = 0x0008, /* XATTR_NAME_HSM */ - LS3_OBJECT_ATTR_LINKS = 0x0010, /* XATTR_NAME_LINK */ - LS3_OBJECT_ATTR_LMV = 0x0020, /* XATTR_NAME_LMV */ - LS3_OBJECT_ATTR_LOV = 0x0040, /* XATTR_NAME_LOV */ - LS3_OBJECT_ATTR_SELF_FID = 0x0080, /* XATTR_NAME_LMA */ - LS3_OBJECT_ATTR_SOM = 0x0100, /* XATTR_NAME_SOM */ - - LS3_OBJECT_ATTR_XATTRS = 0x0200, + /* XATTR_NAME_FID */ + LS3_OBJECT_ATTR_FILTER_FID = BIT(LS3_OBJECT_ATTR_BIT_FILTER_FID), + /* XATTR_NAME_HSM */ + LS3_OBJECT_ATTR_HSM = BIT(LS3_OBJECT_ATTR_BIT_HSM), + /* XATTR_NAME_LINK */ + LS3_OBJECT_ATTR_LINKS = BIT(LS3_OBJECT_ATTR_BIT_LINKS), + /* XATTR_NAME_LMV */ + LS3_OBJECT_ATTR_LMV = BIT(LS3_OBJECT_ATTR_BIT_LMV), + /* XATTR_NAME_LOV */ + LS3_OBJECT_ATTR_LOV = BIT(LS3_OBJECT_ATTR_BIT_LOV), + /* XATTR_NAME_LMA */ + LS3_OBJECT_ATTR_SELF_FID = BIT(LS3_OBJECT_ATTR_BIT_SELF_FID), + /* XATTR_NAME_SOM */ + LS3_OBJECT_ATTR_SOM = BIT(LS3_OBJECT_ATTR_BIT_SOM), + LS3_OBJECT_ATTR_XATTRS = BIT(LS3_OBJECT_ATTR_BIT_XATTRS), /* self_fid on MDT, FID of parent file on OST */ - LS3_OBJECT_ATTR_FILE_FID = 0x0400, + LS3_OBJECT_ATTR_FILE_FID = BIT(LS3_OBJECT_ATTR_BIT_FILE_FID), /* The file size on MDT is always 0 (without Data on MDT). But * Lazy Size on MDT can be used as an estimated size since the * inaccuracy doesn't bother the policy engine. So, if DoM, * use real size; if LSoM exists, use it as file size. */ - LS3_OBJECT_ATTR_SIZE = 0x0800, + LS3_OBJECT_ATTR_SIZE = BIT(LS3_OBJECT_ATTR_BIT_SIZE), /* Paths from fid2path ioctl for LS3_OBJECT_ATTR_FID on client. */ - LS3_OBJECT_ATTR_PATHS = 0x1000, + LS3_OBJECT_ATTR_PATHS = BIT(LS3_OBJECT_ATTR_BIT_PATHS), /* LS3_OBJECT_ATTR_EMPTY TODO Make work for striped directories. */ /* LS3_OBJECT_ATTR_ENTRIES TODO Make work for striped directories. */ - LS3_OBJECT_ATTR_ALL = 0x1fff, + LS3_OBJECT_ATTR_ALL = + LS3_OBJECT_ATTR_BASE | + LS3_OBJECT_ATTR_PROJID | + LS3_OBJECT_ATTR_FILTER_FID | + LS3_OBJECT_ATTR_HSM | + LS3_OBJECT_ATTR_LINKS | + LS3_OBJECT_ATTR_LMV | + LS3_OBJECT_ATTR_LOV | + LS3_OBJECT_ATTR_SELF_FID | + LS3_OBJECT_ATTR_SOM | + LS3_OBJECT_ATTR_XATTRS | + LS3_OBJECT_ATTR_FILE_FID | + LS3_OBJECT_ATTR_SIZE | + LS3_OBJECT_ATTR_PATHS, + LS3_OBJECT_ATTR_DEFAULT = -1U, }; @@ -84,33 +150,33 @@ enum { }; enum ls3_json_attr { - LS3_JSON_ATTR_INO = 1U << LS3_JSON_BIT_INO, - LS3_JSON_ATTR_MODE = 1U << LS3_JSON_BIT_MODE, - LS3_JSON_ATTR_NLINK = 1U << LS3_JSON_BIT_NLINK, - LS3_JSON_ATTR_UID = 1U << LS3_JSON_BIT_UID, - LS3_JSON_ATTR_GID = 1U << LS3_JSON_BIT_GID, - LS3_JSON_ATTR_PROJID = 1U << LS3_JSON_BIT_PROJID, - LS3_JSON_ATTR_FLAGS = 1U << LS3_JSON_BIT_FLAGS, - LS3_JSON_ATTR_ATIME = 1U << LS3_JSON_BIT_ATIME, - LS3_JSON_ATTR_MTIME = 1U << LS3_JSON_BIT_MTIME, - LS3_JSON_ATTR_CTIME = 1U << LS3_JSON_BIT_CTIME, - LS3_JSON_ATTR_CRTIME = 1U << LS3_JSON_BIT_CRTIME, - LS3_JSON_ATTR_SIZE = 1U << LS3_JSON_BIT_SIZE, - LS3_JSON_ATTR_BLOCKS = 1U << LS3_JSON_BIT_BLOCKS, - LS3_JSON_ATTR_FILE_FID = 1U << LS3_JSON_BIT_FILE_FID, - LS3_JSON_ATTR_SELF_FID = 1U << LS3_JSON_BIT_SELF_FID, - LS3_JSON_ATTR_FILTER_FID = 1U << LS3_JSON_BIT_FILTER_FID, - LS3_JSON_ATTR_LMA = 1U << LS3_JSON_BIT_LMA, - LS3_JSON_ATTR_HSM = 1U << LS3_JSON_BIT_HSM, - LS3_JSON_ATTR_LOV = 1U << LS3_JSON_BIT_LOV, - LS3_JSON_ATTR_LMV = 1U << LS3_JSON_BIT_LMV, - LS3_JSON_ATTR_POOLS = 1U << LS3_JSON_BIT_POOLS, - LS3_JSON_ATTR_LINKS = 1U << LS3_JSON_BIT_LINKS, - LS3_JSON_ATTR_PATHS = 1U << LS3_JSON_BIT_PATHS, - LS3_JSON_ATTR_SOM = 1U << LS3_JSON_BIT_SOM, - LS3_JSON_ATTR_XATTRS = 1U << LS3_JSON_BIT_XATTRS, - LS3_JSON_ATTR_DEVICE_NAME = 1U << LS3_JSON_BIT_DEVICE_NAME, - LS3_JSON_ATTR_DEVICE_PATH = 1U << LS3_JSON_BIT_DEVICE_PATH, + LS3_JSON_ATTR_INO = BIT(LS3_JSON_BIT_INO), + LS3_JSON_ATTR_MODE = BIT(LS3_JSON_BIT_MODE), + LS3_JSON_ATTR_NLINK = BIT(LS3_JSON_BIT_NLINK), + LS3_JSON_ATTR_UID = BIT(LS3_JSON_BIT_UID), + LS3_JSON_ATTR_GID = BIT(LS3_JSON_BIT_GID), + LS3_JSON_ATTR_PROJID = BIT(LS3_JSON_BIT_PROJID), + LS3_JSON_ATTR_FLAGS = BIT(LS3_JSON_BIT_FLAGS), + LS3_JSON_ATTR_ATIME = BIT(LS3_JSON_BIT_ATIME), + LS3_JSON_ATTR_MTIME = BIT(LS3_JSON_BIT_MTIME), + LS3_JSON_ATTR_CTIME = BIT(LS3_JSON_BIT_CTIME), + LS3_JSON_ATTR_CRTIME = BIT(LS3_JSON_BIT_CRTIME), + LS3_JSON_ATTR_SIZE = BIT(LS3_JSON_BIT_SIZE), + LS3_JSON_ATTR_BLOCKS = BIT(LS3_JSON_BIT_BLOCKS), + LS3_JSON_ATTR_FILE_FID = BIT(LS3_JSON_BIT_FILE_FID), + LS3_JSON_ATTR_SELF_FID = BIT(LS3_JSON_BIT_SELF_FID), + LS3_JSON_ATTR_FILTER_FID = BIT(LS3_JSON_BIT_FILTER_FID), + LS3_JSON_ATTR_LMA = BIT(LS3_JSON_BIT_LMA), + LS3_JSON_ATTR_HSM = BIT(LS3_JSON_BIT_HSM), + LS3_JSON_ATTR_LOV = BIT(LS3_JSON_BIT_LOV), + LS3_JSON_ATTR_LMV = BIT(LS3_JSON_BIT_LMV), + LS3_JSON_ATTR_POOLS = BIT(LS3_JSON_BIT_POOLS), + LS3_JSON_ATTR_LINKS = BIT(LS3_JSON_BIT_LINKS), + LS3_JSON_ATTR_PATHS = BIT(LS3_JSON_BIT_PATHS), + LS3_JSON_ATTR_SOM = BIT(LS3_JSON_BIT_SOM), + LS3_JSON_ATTR_XATTRS = BIT(LS3_JSON_BIT_XATTRS), + LS3_JSON_ATTR_DEVICE_NAME = BIT(LS3_JSON_BIT_DEVICE_NAME), + LS3_JSON_ATTR_DEVICE_PATH = BIT(LS3_JSON_BIT_DEVICE_PATH), /* Print the fast and mostly correct attributes by default. */ LS3_JSON_ATTR_DEFAULT = diff --git a/lipe/src/lipe_scan3/ls3_scan.c b/lipe/src/lipe_scan3/ls3_scan.c index 08256ec..fe08362 100644 --- a/lipe/src/lipe_scan3/ls3_scan.c +++ b/lipe/src/lipe_scan3/ls3_scan.c @@ -50,7 +50,8 @@ struct ls3_scan_control { size_t sc_thread_count; intmax_t sc_thread_rc_max; intmax_t sc_break_rc; - uintmax_t sc_read_attr_error_count; + uintmax_t sc_read_attr_error_count[LS3_OBJECT_ATTR_BIT_MAX]; + uintmax_t sc_read_attr_error_count_total; uintmax_t sc_other_error_count; }; @@ -64,7 +65,7 @@ struct ls3_thread_info { unsigned long ti_group_start; unsigned long ti_group_current; unsigned long ti_group_end; - uintmax_t ti_read_attr_error_count; + uintmax_t ti_read_attr_error_count[LS3_OBJECT_ATTR_BIT_MAX]; uintmax_t ti_other_error_count; int ti_started; int ti_should_stop; /* Use __ATOMIC_RELAXED. */ @@ -237,6 +238,18 @@ ldiskfs_read_attr_links(struct ls3_instance *li, size_t value_size = 0; int rc; + if (li->li_device_is_ost) { + /* No links xattr on OST */ + return 0; + } + + if (!li->li_device_is_mdt) { + LS3_ERROR_ONCE("cannot get links on device '%s' " + "with unrecognized type\n", + li->li_device_path); + return -EINVAL; + } + assert(lipe_list_empty(&loa->loa_links)); /* We use the link xattr plus caching to speed up paths but we @@ -771,7 +784,7 @@ out: ext2fs_xattrs_close(&lo.u.lo_ldiskfs.lol_xattr_handle); lipe_object_attrs_fini(&loa); -} +} /* ls3_scan_inode */ static int ldiskfs_scan_groups(ext2_inode_scan scan, ext2_filsys fs, @@ -1002,7 +1015,7 @@ static void ls3_scan_control_stop(struct ls3_scan_control *sc) static int ls3_scan_control_join(struct ls3_scan_control *sc) { int rc = 0; - int i; + int i, j; for (i = 0; i < sc->sc_thread_count; i++) { struct ls3_thread_info *ti = &sc->sc_thread_infos[i]; @@ -1028,7 +1041,13 @@ static int ls3_scan_control_join(struct ls3_scan_control *sc) if (sc->sc_thread_rc_max < imaxabs(thread_rc)) sc->sc_thread_rc_max = imaxabs(thread_rc); - sc->sc_read_attr_error_count += ti->ti_read_attr_error_count; + for (j = 0; j < ARRAY_SIZE(ti->ti_read_attr_error_count); j++) { + sc->sc_read_attr_error_count[j] += + ti->ti_read_attr_error_count[j]; + sc->sc_read_attr_error_count_total += + ti->ti_read_attr_error_count[j]; + } + sc->sc_other_error_count += ti->ti_other_error_count; } @@ -1048,6 +1067,7 @@ static intmax_t ls3_scan_fs(struct ls3_instance *li, ext2_filsys fs, size_t thre .sc_group_desc_count = fs->group_desc_count, }; intmax_t rc, rc2; + enum ls3_object_attr_bit_pos pos; LS3_DEBUG_U(sc.sc_group_desc_count); @@ -1078,12 +1098,18 @@ static intmax_t ls3_scan_fs(struct ls3_instance *li, ext2_filsys fs, size_t thre LS3_DEBUG_D(rc); LS3_DEBUG_D(sc.sc_thread_rc_max); - LS3_DEBUG_U(sc.sc_read_attr_error_count); - LS3_DEBUG_U(sc.sc_other_error_count); - if (sc.sc_read_attr_error_count > 0) - LS3_WARNING("device '%s': read attr error count %"PRIuMAX"\n", - li->li_device_path, sc.sc_read_attr_error_count); + if (sc.sc_read_attr_error_count_total > 0) { + LS3_WARNING("device '%s': read attr error count %"PRIuMAX" :\n", + li->li_device_path, sc.sc_read_attr_error_count_total); + + for (pos = 0; pos < ARRAY_SIZE(sc.sc_read_attr_error_count); pos++) { + if (sc.sc_read_attr_error_count[pos] != 0) + LS3_WARNING(" '%s'\t: %"PRIuMAX"\n", + ls3_object_attr_bit_pos2str(pos), + (uintmax_t)(sc.sc_read_attr_error_count[pos])); + } + } if (sc.sc_other_error_count > 0) LS3_WARNING("device '%s': other error count %"PRIuMAX"\n", @@ -1389,7 +1415,42 @@ SCM ls3_policy_exception_handler(SCM key, SCM args) return SCM_BOOL_T; if (scm_is_eq(key, ls3_sym_read_attr_error)) { - ti->ti_read_attr_error_count++; + size_t len, i; + unsigned long bits; + + const SCM vector = scm_make_vector(scm_length(args), SCM_UNDEFINED); + + len = scm_c_vector_length(vector); + for (i = 0; i < len && scm_is_pair(args); i++) { + scm_c_vector_set_x(vector, i, scm_car(args)); + args = scm_cdr(args); + } + + bits = scm_to_ulong(SCM_SIMPLE_VECTOR_REF(vector, 1)); + + bits &= LS3_OBJECT_ATTR_ALL; + + while (bits) { + enum ls3_object_attr_bit_pos pos = __builtin_ffsl(bits)-1; + + ti->ti_read_attr_error_count[pos]++; + + /* Report each get attribute warning only when enabled */ + if (ls3_warn_get_attr) { + int64_t loa_ino = + scm_to_ulong(SCM_SIMPLE_VECTOR_REF(vector, 0)); + int error = + scm_to_int(SCM_SIMPLE_VECTOR_REF(vector, 2)); + + LS3_WARNING("read attr error: ino: %llu, " + "attr: '%s', error: %d\n", + (unsigned long long int)loa_ino, + ls3_object_attr_bit_pos2str(pos), + error); + } + + bits &= ~(1UL << pos); + } } else if (scm_is_eq(key, ls3_sym_scan_break)) { struct ls3_scan_control *sc = ti->ti_scan_control; SCM rc; diff --git a/lipe/src/lipe_scan3/tests/lipe.scm b/lipe/src/lipe_scan3/tests/lipe.scm index 446ea9a..4de0ab9 100644 --- a/lipe/src/lipe_scan3/tests/lipe.scm +++ b/lipe/src/lipe_scan3/tests/lipe.scm @@ -7,6 +7,13 @@ (assert (eq? #t (lipe-debug-enable #f))) (assert (eq? #f (lipe-debug-enable))) +(assert (procedure? lipe-warnings-get-attr-enable)) +(assert (eq? #f (lipe-warnings-get-attr-enable))) +(assert (eq? #f (lipe-warnings-get-attr-enable #t))) +(assert (eq? #t (lipe-warnings-get-attr-enable))) +(assert (eq? #t (lipe-warnings-get-attr-enable #f))) +(assert (eq? #f (lipe-warnings-get-attr-enable))) + (assert (procedure? lipe-gettid)) (assert (integer? (lipe-gettid))) (assert (positive? (lipe-gettid)))