'lfs find' stops as soon as it encounters an error, such as EACCES.
Change the behavior to match the regular find command: just note the
failure but continue on, returning a non-zero exit code at the end.
Signed-off-by: Matt Ezell <ezellma@ornl.gov>
Change-Id: I16ca35ec193e36134e7b93d91a20ff1d0778fe60
Reviewed-on: http://review.whamcloud.com/9794
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: James Nunez <james.a.nunez@intel.com>
Reviewed-by: James Simmons <uja.ornl@gmail.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
}
run_test 56y "lfs find -L raid0|released"
+test_56z() { # LU-4824
+ # This checks to make sure 'lfs find' continues after errors
+ # There are two classes of errors that should be caught:
+ # - If multiple paths are provided, all should be searched even if one
+ # errors out
+ # - If errors are encountered during the search, it should not terminate
+ # early
+ local i
+ test_mkdir $DIR/$tdir
+ for i in d{0..9}; do
+ test_mkdir $DIR/$tdir/$i
+ done
+ touch $DIR/$tdir/d{0..9}/$tfile
+ $LFS find $DIR/non_existent_dir $DIR/$tdir &&
+ error "$LFS find did not return an error"
+ # Make a directory unsearchable. This should NOT be the last entry in
+ # directory order. Arbitrarily pick the 6th entry
+ chmod 700 $(lfs find $DIR/$tdir -type d | sed '6!d')
+ local count=$($RUNAS $LFS find $DIR/non_existent $DIR/$tdir | wc -l)
+ # The user should be able to see 10 directories and 9 files
+ [ $count == 19 ] || error "$LFS find did not continue after error"
+}
+run_test 56z "lfs find should continue after an error"
+
test_57a() {
[ $PARALLEL == "yes" ] && skip "skip parallel run" && return
# note test will not do anything if MDS is not local
#define FIND_POOL_OPT 3
static int lfs_find(int argc, char **argv)
{
- int c, ret;
+ int c, rc;
+ int ret = 0;
time_t t;
struct find_param param = {
.fp_max_depth = -1,
xsign = ¶m.fp_msign;
param.fp_exclude_mtime = !!neg_opt;
}
- ret = set_time(&t, xtime, optarg);
- if (ret == INT_MAX) {
- ret = -1;
- goto err;
- }
- if (ret)
- *xsign = ret;
- break;
+ rc = set_time(&t, xtime, optarg);
+ if (rc == INT_MAX) {
+ ret = -1;
+ goto err;
+ }
+ if (rc)
+ *xsign = rc;
+ break;
case 'c':
if (optarg[0] == '+') {
param.stripecount_sign = -1;
break;
case 'g':
case 'G':
- ret = name2id(¶m.fp_gid, optarg, GROUP);
- if (ret) {
+ rc = name2id(¶m.fp_gid, optarg, GROUP);
+ if (rc) {
param.fp_gid = strtoul(optarg, &endptr, 10);
if (*endptr != '\0') {
fprintf(stderr, "Group/GID: %s cannot "
break;
case 'u':
case 'U':
- ret = name2id(¶m.fp_uid, optarg, USER);
- if (ret) {
+ rc = name2id(¶m.fp_uid, optarg, USER);
+ if (rc) {
param.fp_uid = strtoul(optarg, &endptr, 10);
if (*endptr != '\0') {
fprintf(stderr, "User/UID: %s cannot "
pathend = argc;
}
- do {
- ret = llapi_find(argv[pathstart], ¶m);
- } while (++pathstart < pathend && !ret);
+ do {
+ rc = llapi_find(argv[pathstart], ¶m);
+ if (rc != 0 && ret == 0)
+ ret = rc;
+ } while (++pathstart < pathend);
if (ret)
fprintf(stderr, "error: %s failed for %s.\n",
int len, ret;
DIR *d, *p = NULL;
- ret = 0;
- len = strlen(path);
+ ret = 0;
+ len = strlen(path);
d = opendir(path);
if (!d && errno != ENOTDIR) {
if (sem_init && (ret = sem_init(path, parent ?: p, &d, data, de)))
goto err;
- if (!d || (param->get_lmv && !param->recursive)) {
- ret = 0;
+ if (!d || (param->get_lmv && !param->recursive))
goto out;
- }
while ((dent = readdir64(d)) != NULL) {
+ int rc;
+
param->have_fileinfo = 0;
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
if (dent->d_type == DT_UNKNOWN) {
lstat_t *st = ¶m->lmd->lmd_st;
- ret = get_lmd_info(path, d, NULL, param->lmd,
+ rc = get_lmd_info(path, d, NULL, param->lmd,
param->lumlen);
- if (ret == 0)
+ if (rc == 0)
dent->d_type = IFTODT(st->st_mode);
+ else if (ret == 0)
+ ret = rc;
- if (ret == -ENOENT)
- continue;
+ if (rc == -ENOENT)
+ continue;
}
switch (dent->d_type) {
case DT_UNKNOWN:
"error: %s: '%s' is UNKNOWN type %d",
__func__, dent->d_name, dent->d_type);
break;
- case DT_DIR:
- ret = llapi_semantic_traverse(path, size, d, sem_init,
- sem_fini, data, dent);
- if (ret < 0)
- goto out;
- break;
- default:
- ret = 0;
- if (sem_init) {
- ret = sem_init(path, d, NULL, data, dent);
- if (ret < 0)
- goto out;
- }
- if (sem_fini && ret == 0)
- sem_fini(path, d, NULL, data, dent);
+ case DT_DIR:
+ rc = llapi_semantic_traverse(path, size, d, sem_init,
+ sem_fini, data, dent);
+ if (rc != 0 && ret == 0)
+ ret = rc;
+ break;
+ default:
+ rc = 0;
+ if (sem_init) {
+ rc = sem_init(path, d, NULL, data, dent);
+ if (rc < 0 && ret == 0)
+ ret = rc;
+ }
+ if (sem_fini && rc == 0)
+ sem_fini(path, d, NULL, data, dent);
}
}
closedir(d);
if (p)
closedir(p);
- return ret;
+ return ret;
}
static int param_callback(char *path, semantic_func_t sem_init,