Whamcloud - gitweb
b=11694
[fs/lustre-release.git] / lustre / utils / liblustreapi.c
index 5ea3ee8..185be04 100644 (file)
 #include <obd_lov.h>
 #include <lustre/liblustreapi.h>
 
-static void err_msg(char *fmt, ...)
+static unsigned llapi_dir_filetype_table[] = {
+        [DT_UNKNOWN]= 0,
+        [DT_FIFO]= S_IFIFO,
+        [DT_CHR] = S_IFCHR,
+        [DT_DIR] = S_IFDIR,
+        [DT_BLK] = S_IFBLK,
+        [DT_REG] = S_IFREG,
+        [DT_LNK] = S_IFLNK,
+        [DT_SOCK]= S_IFSOCK,
+#if defined(DT_DOOR) && defined(S_IFDOOR)
+        [DT_DOOR]= S_IFDOOR,
+#endif
+};
+
+#if defined(DT_DOOR) && defined(S_IFDOOR)
+static const int DT_MAX = DT_DOOR;
+#else
+static const int DT_MAX = DT_SOCK;
+#endif
+
+static unsigned llapi_filetype_dir_table[] = {
+        [0]= DT_UNKNOWN,
+        [S_IFIFO]= DT_FIFO,
+        [S_IFCHR] = DT_CHR,
+        [S_IFDIR] = DT_DIR,
+        [S_IFBLK] = DT_BLK,
+        [S_IFREG] = DT_REG,
+        [S_IFLNK] = DT_LNK,
+        [S_IFSOCK]= DT_SOCK,
+#if defined(DT_DOOR) && defined(S_IFDOOR)
+        [S_IFDOOR]= DT_DOOR,
+#endif
+};
+
+#if defined(DT_DOOR) && defined(S_IFDOOR)
+static const int S_IFMAX = DT_DOOR;
+#else
+static const int S_IFMAX = DT_SOCK;
+#endif
+
+/* liblustreapi message level */
+static int llapi_msg_level = LLAPI_MSG_MAX;
+
+void llapi_msg_set_level(int level)
+{
+        /* ensure level is in the good range */
+        if (level < LLAPI_MSG_OFF)
+                llapi_msg_level = LLAPI_MSG_OFF;
+        else if (level > LLAPI_MSG_MAX)
+                llapi_msg_level = LLAPI_MSG_MAX;
+        else
+                llapi_msg_level = level;
+}
+
+void llapi_err(int level, char *fmt, ...)
 {
         va_list args;
         int tmp_errno = abs(errno);
 
+        if ((level & LLAPI_MSG_MASK) > llapi_msg_level)
+                return;
+
         va_start(args, fmt);
         vfprintf(stderr, fmt, args);
         va_end(args);
-        fprintf(stderr, ": %s (%d)\n", strerror(tmp_errno), tmp_errno);
+
+        if (level & LLAPI_MSG_NO_ERRNO)
+                fprintf(stderr, "\n");
+        else
+                fprintf(stderr, ": %s (%d)\n", strerror(tmp_errno), tmp_errno);
+}
+
+#define llapi_err_noerrno(level, fmt, a...)                             \
+        llapi_err((level) | LLAPI_MSG_NO_ERRNO, fmt, ## a)
+
+void llapi_printf(int level, char *fmt, ...)
+{
+        va_list args;
+
+        if ((level & LLAPI_MSG_MASK) > llapi_msg_level)
+                return;
+
+        va_start(args, fmt);
+        vfprintf(stdout, fmt, args);
+        va_end(args);
+}
+
+int parse_size(char *optarg, unsigned long long *size,
+               unsigned long long *size_units)
+{
+        char *end;
+
+        *size = strtoul(optarg, &end, 0);
+
+        if (*end != '\0') {
+                if ((*end == 'b') && *(end+1) == '\0' &&
+                    (*size & (~0ULL << (64 - 9))) == 0) {
+                        *size <<= 9;
+                        *size_units = 1 << 9;
+                } else if ((*end == 'k' || *end == 'K') &&
+                           *(end+1) == '\0' && (*size &
+                           (~0ULL << (64 - 10))) == 0) {
+                        *size <<= 10;
+                        *size_units = 1 << 10;
+                } else if ((*end == 'm' || *end == 'M') &&
+                           *(end+1) == '\0' && (*size &
+                           (~0ULL << (64 - 20))) == 0) {
+                        *size <<= 20;
+                        *size_units = 1 << 20;
+                } else if ((*end == 'g' || *end == 'G') &&
+                           *(end+1) == '\0' && (*size &
+                           (~0ULL << (64 - 30))) == 0) {
+                        *size <<= 30;
+                        *size_units = 1 << 30;
+                } else if ((*end == 't' || *end == 'T') &&
+                           *(end+1) == '\0' && (*size &
+                           (~0ULL << (64 - 40))) == 0) {
+                        *size <<= 40;
+                        *size_units = 1ULL << 40;
+                } else if ((*end == 'p' || *end == 'P') &&
+                           *(end+1) == '\0' && (*size &
+                           (~0ULL << (64 - 50))) == 0) {
+                        *size <<= 50;
+                        *size_units = 1ULL << 50;
+                } else if ((*end == 'e' || *end == 'E') &&
+                           *(end+1) == '\0' && (*size &
+                           (~0ULL << (64 - 60))) == 0) {
+                        *size <<= 60;
+                        *size_units = 1ULL << 60;
+                } else {
+                        return -1;
+                }
+        }
+
+        return 0;
 }
 
 int llapi_file_open(const char *name, int flags, int mode,
@@ -84,7 +210,7 @@ int llapi_file_open(const char *name, int flags, int mode,
 
         if (fd < 0) {
                 rc = -errno;
-                err_msg("unable to open '%s'", name);
+                llapi_err(LLAPI_MSG_ERROR, "unable to open '%s'", name);
                 return rc;
         }
 
@@ -93,29 +219,35 @@ int llapi_file_open(const char *name, int flags, int mode,
         page_size = LOV_MIN_STRIPE_SIZE;
         if (getpagesize() > page_size) {
                 page_size = getpagesize();
-                fprintf(stderr, "warning: your page size (%u) is larger than "
-                        "expected (%u).\n", page_size, LOV_MIN_STRIPE_SIZE);
+                llapi_err_noerrno(LLAPI_MSG_WARN, 
+                                  "warning: your page size (%u) is "
+                                  "larger than expected (%u)", page_size, 
+                                  LOV_MIN_STRIPE_SIZE);
         }
         if (stripe_size < 0 || (stripe_size & (LOV_MIN_STRIPE_SIZE - 1))) {
                 errno = rc = -EINVAL;
-                err_msg("error: bad stripe_size %lu, must be an even "
-                        "multiple of %d bytes", stripe_size, page_size);
+                llapi_err(LLAPI_MSG_ERROR, "error: bad stripe_size %lu, "
+                          "must be an even multiple of %d bytes", 
+                          stripe_size, page_size);
                 goto out;
         }
         if (stripe_offset < -1 || stripe_offset > MAX_OBD_DEVICES) {
                 errno = rc = -EINVAL;
-                err_msg("error: bad stripe offset %d", stripe_offset);
+                llapi_err(LLAPI_MSG_ERROR, "error: bad stripe offset %d", 
+                          stripe_offset);
                 goto out;
         }
         if (stripe_count < -1 || stripe_count > LOV_MAX_STRIPE_COUNT) {
                 errno = rc = -EINVAL;
-                err_msg("error: bad stripe count %d", stripe_count);
+                llapi_err(LLAPI_MSG_ERROR, "error: bad stripe count %d", 
+                          stripe_count);
                 goto out;
         }
         if (stripe_count > 0 && (__u64)stripe_size * stripe_count > 0xffffffff){
                 errno = rc = -EINVAL;
-                err_msg("error: stripe_size %lu * stripe_count %u "
-                        "exceeds 4GB", stripe_size, stripe_count);
+                llapi_err(LLAPI_MSG_ERROR, "error: stripe_size %lu * "
+                          "stripe_count %u exceeds 4GB", stripe_size, 
+                          stripe_count);
                 goto out;
         }
 
@@ -132,8 +264,9 @@ int llapi_file_open(const char *name, int flags, int mode,
                 if (errno != EEXIST && errno != EALREADY)
                         errmsg = strerror(errno);
 
-                fprintf(stderr, "error on ioctl "LPX64" for '%s' (%d): %s\n",
-                        (__u64)LL_IOC_LOV_SETSTRIPE, name, fd, errmsg);
+                llapi_err_noerrno(LLAPI_MSG_ERROR,
+                                  "error on ioctl "LPX64" for '%s' (%d): %s",
+                                  (__u64)LL_IOC_LOV_SETSTRIPE, name, fd, errmsg);
         }
 out:
         if (rc) {
@@ -158,7 +291,8 @@ int llapi_file_create(const char *name, unsigned long stripe_size,
         return 0;
 }
 
-typedef int (semantic_func_t)(char *path, DIR *parent, DIR *d, void *data);
+typedef int (semantic_func_t)(char *path, DIR *parent, DIR *d,
+                              void *data, struct dirent64 *de);
 
 #define MAX_LOV_UUID_COUNT      max(LOV_MAX_STRIPE_COUNT, 1000)
 #define OBD_NOT_FOUND           (-1)
@@ -167,22 +301,33 @@ static int common_param_init(struct find_param *param)
 {
         param->lumlen = lov_mds_md_size(MAX_LOV_UUID_COUNT);
         if ((param->lmd = malloc(sizeof(lstat_t) + param->lumlen)) == NULL) {
-                err_msg("error: allocation of %d bytes for ioctl",
-                        sizeof(lstat_t) + param->lumlen);
+                llapi_err(LLAPI_MSG_ERROR, 
+                          "error: allocation of %d bytes for ioctl",
+                          sizeof(lstat_t) + param->lumlen);
                 return -ENOMEM;
         }
 
         param->got_uuids = 0;
+        param->obdindexes = NULL;
         param->obdindex = OBD_NOT_FOUND;
         return 0;
 }
 
 static void find_param_fini(struct find_param *param)
 {
+        if (param->obdindexes)
+                free(param->obdindexes);
+
         if (param->lmd)
                 free(param->lmd);
 }
 
+/*
+ * If uuidp is NULL, return the number of available obd uuids.
+ * If uuidp is non-NULL, then it will return the uuids of the obds. If
+ * there are more OSTs then allocated to uuidp, then an error is returned with
+ * the ost_count set to number of available obd uuids.
+ */
 int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count)
 {
         char lov_name[sizeof(struct obd_uuid)];
@@ -194,7 +339,7 @@ int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count)
         rc = ioctl(fd, OBD_IOC_GETNAME, (void *) lov_name);
         if (rc) {
                 rc = errno;
-                err_msg("error: can't get lov name.");
+                llapi_err(LLAPI_MSG_ERROR, "error: can't get lov name");
                 return rc;
         }
 
@@ -204,23 +349,30 @@ int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count)
         fp = fopen(buf, "r");
         if (fp == NULL) {
                 rc = errno;
-                err_msg("error: opening '%s'", buf);
+                llapi_err(LLAPI_MSG_ERROR, "error: opening '%s'", buf);
                 return rc;
         }
 
-        while ((fgets(buf, sizeof(buf), fp) != NULL) && index < *ost_count) {
-                if (sscanf(buf, "%d: %s", &index, uuidp[index].uuid) < 2)
-                        break;
+        while (fgets(buf, sizeof(buf), fp) != NULL) {
+                if (uuidp && (index < *ost_count)) {
+                        if (sscanf(buf, "%d: %s", &index, uuidp[index].uuid) <2)
+                                break;
+                }
                 index++;
         }
 
         fclose(fp);
-        *ost_count = index;
 
+        if (uuidp && (index >= *ost_count))
+                return -EOVERFLOW;
+
+        *ost_count = index;
         return rc;
 }
 
-static int setup_obd_uuids(DIR *dir, char *dname, struct find_param *param)
+/* Here, param->obduuid points to a single obduuid, the index of which is
+ * returned in param->obdindex */
+static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param)
 {
         char uuid[sizeof(struct obd_uuid)];
         char buf[1024];
@@ -232,7 +384,8 @@ static int setup_obd_uuids(DIR *dir, char *dname, struct find_param *param)
         if (rc) {
                 if (errno != ENOTTY) {
                         rc = errno;
-                        err_msg("error: can't get lov name: %s", dname);
+                        llapi_err(LLAPI_MSG_ERROR, 
+                                  "error: can't get lov name: %s", dname);
                 } else {
                         rc = 0;
                 }
@@ -247,12 +400,12 @@ static int setup_obd_uuids(DIR *dir, char *dname, struct find_param *param)
         fp = fopen(buf, "r");
         if (fp == NULL) {
                 rc = errno;
-                err_msg("error: opening '%s'", buf);
+                llapi_err(LLAPI_MSG_ERROR, "error: opening '%s'", buf);
                 return rc;
         }
 
         if (!param->obduuid && !param->quiet && !param->obds_printed)
-                printf("OBDS:\n");
+                llapi_printf(LLAPI_MSG_NORMAL, "OBDS:\n");
 
         while (fgets(buf, sizeof(buf), fp) != NULL) {
                 if (sscanf(buf, "%d: %s", &index, uuid) < 2)
@@ -266,7 +419,7 @@ static int setup_obd_uuids(DIR *dir, char *dname, struct find_param *param)
                         }
                 } else if (!param->quiet && !param->obds_printed) {
                         /* Print everything */
-                        printf("%s", buf);
+                        llapi_printf(LLAPI_MSG_NORMAL, "%s", buf);
                 }
         }
         param->obds_printed = 1;
@@ -275,14 +428,75 @@ static int setup_obd_uuids(DIR *dir, char *dname, struct find_param *param)
 
         if (!param->quiet && param->obduuid &&
             (param->obdindex == OBD_NOT_FOUND)) {
-                fprintf(stderr, "error: %s: unknown obduuid: %s\n",
-                        __FUNCTION__, param->obduuid->uuid);
+                llapi_err_noerrno(LLAPI_MSG_ERROR, 
+                                  "error: %s: unknown obduuid: %s",
+                                  __FUNCTION__, param->obduuid->uuid);
                 //rc = EINVAL;
         }
 
         return (rc);
 }
 
+/* In this case, param->obduuid will be an array of obduuids and
+ * obd index for all these obduuids will be returned in
+ * param->obdindexes */
+static int setup_obd_indexes(DIR *dir, struct find_param *param)
+{
+        struct obd_uuid *uuids = NULL;
+        int obdcount = INIT_ALLOC_NUM_OSTS;
+        int ret, obd_valid = 0, obdnum, i;
+
+        uuids = (struct obd_uuid *)malloc(INIT_ALLOC_NUM_OSTS *
+                                          sizeof(struct obd_uuid));
+        if (uuids == NULL)
+                return -ENOMEM;
+
+retry_get_uuids:
+        ret = llapi_lov_get_uuids(dirfd(dir), uuids,
+                                  &obdcount);
+        if (ret) {
+                struct obd_uuid *uuids_temp;
+
+                if (ret == -EOVERFLOW) {
+                        uuids_temp = realloc(uuids, obdcount *
+                                             sizeof(struct obd_uuid));
+                        if (uuids_temp != NULL)
+                                goto retry_get_uuids;
+                        else
+                                ret = -ENOMEM;
+                }
+
+                llapi_err(LLAPI_MSG_ERROR, "get ost uuid failed");
+                return ret;
+        }
+
+        param->obdindexes = malloc(param->num_obds * sizeof(param->obdindex));
+        if (param->obdindexes == NULL)
+                return -ENOMEM;
+
+        for (obdnum = 0; obdnum < param->num_obds; obdnum++) {
+                for (i = 0; i <= obdcount; i++) {
+                        if (strcmp((char *)&param->obduuid[obdnum].uuid,
+                                   (char *)&uuids[i]) == 0) {
+                                param->obdindexes[obdnum] = i;
+                                obd_valid++;
+                                break;
+                        }
+                }
+                if (i == obdcount)
+                        param->obdindexes[obdnum] = OBD_NOT_FOUND;
+        }
+
+        if (obd_valid == 0)
+                param->obdindex = OBD_NOT_FOUND;
+        else
+                param->obdindex = obd_valid;
+
+        param->got_uuids = 1;
+
+        return 0;
+}
+
 void lov_dump_user_lmm_v1(struct lov_user_md_v1 *lum, char *path, int is_dir,
                           int obdindex, int quiet, int header, int body)
 {
@@ -291,53 +505,66 @@ void lov_dump_user_lmm_v1(struct lov_user_md_v1 *lum, char *path, int is_dir,
         if (obdindex != OBD_NOT_FOUND) {
                 for (i = 0; !is_dir && i < lum->lmm_stripe_count; i++) {
                         if (obdindex == lum->lmm_objects[i].l_ost_idx) {
-                                printf("%s\n", path);
+                                llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path);
                                 obdstripe = 1;
                                 break;
                         }
                 }
         } else if (!quiet) {
-                printf("%s\n", path);
+                llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path);
                 obdstripe = 1;
         }
 
         /* if it's a directory */
         if (is_dir) {
                 if (obdstripe == 1) {
-                        printf("default stripe_count: %d stripe_size: %u "
-                               "stripe_offset: %d\n",
-                               lum->lmm_stripe_count == (__u16)-1 ? -1 :
-                                        lum->lmm_stripe_count,
-                               lum->lmm_stripe_size,
-                               lum->lmm_stripe_offset == (__u16)-1 ? -1 :
-                                        lum->lmm_stripe_offset);
+                        if (lum->lmm_object_gr == LOV_OBJECT_GROUP_DEFAULT) {
+                                llapi_printf(LLAPI_MSG_NORMAL, "(Default) ");
+                                lum->lmm_object_gr = LOV_OBJECT_GROUP_CLEAR;
+                        }
+                        llapi_printf(LLAPI_MSG_NORMAL, 
+                                     "stripe_count: %d stripe_size: %u "
+                                     "stripe_offset: %d\n",
+                                     lum->lmm_stripe_count == (__u16)-1 ? -1 :
+                                     lum->lmm_stripe_count,
+                                     lum->lmm_stripe_size,
+                                     lum->lmm_stripe_offset == (__u16)-1 ? -1 :
+                                     lum->lmm_stripe_offset);
                 }
                 return;
         }
 
         if (header && (obdstripe == 1)) {
-                printf("lmm_magic:          0x%08X\n",  lum->lmm_magic);
-                printf("lmm_object_gr:      "LPX64"\n", lum->lmm_object_gr);
-                printf("lmm_object_id:      "LPX64"\n", lum->lmm_object_id);
-                printf("lmm_stripe_count:   %u\n", (int)lum->lmm_stripe_count);
-                printf("lmm_stripe_size:    %u\n",      lum->lmm_stripe_size);
-                printf("lmm_stripe_pattern: %x\n",      lum->lmm_pattern);
+                llapi_printf(LLAPI_MSG_NORMAL, 
+                             "lmm_magic:          0x%08X\n",  lum->lmm_magic);
+                llapi_printf(LLAPI_MSG_NORMAL, 
+                             "lmm_object_gr:      "LPX64"\n", lum->lmm_object_gr);
+                llapi_printf(LLAPI_MSG_NORMAL, 
+                             "lmm_object_id:      "LPX64"\n", lum->lmm_object_id);
+                llapi_printf(LLAPI_MSG_NORMAL, 
+                             "lmm_stripe_count:   %u\n", (int)lum->lmm_stripe_count);
+                llapi_printf(LLAPI_MSG_NORMAL, 
+                             "lmm_stripe_size:    %u\n",      lum->lmm_stripe_size);
+                llapi_printf(LLAPI_MSG_NORMAL, 
+                             "lmm_stripe_pattern: %x\n",      lum->lmm_pattern);
         }
 
         if (body) {
                 if ((!quiet) && (obdstripe == 1))
-                        printf("\tobdidx\t\t objid\t\tobjid\t\t group\n");
+                        llapi_printf(LLAPI_MSG_NORMAL, 
+                                     "\tobdidx\t\t objid\t\tobjid\t\t group\n");
 
                 for (i = 0; i < lum->lmm_stripe_count; i++) {
                         int idx = lum->lmm_objects[i].l_ost_idx;
                         long long oid = lum->lmm_objects[i].l_object_id;
                         long long gr = lum->lmm_objects[i].l_object_gr;
                         if ((obdindex == OBD_NOT_FOUND) || (obdindex == idx))
-                                printf("\t%6u\t%14llu\t%#13llx\t%14llu%s\n",
-                                       idx, oid, oid, gr,
-                                       obdindex == idx ? " *" : "");
+                                llapi_printf(LLAPI_MSG_NORMAL, 
+                                             "\t%6u\t%14llu\t%#13llx\t%14llu%s\n",
+                                             idx, oid, oid, gr,
+                                             obdindex == idx ? " *" : "");
                 }
-                printf("\n");
+                llapi_printf(LLAPI_MSG_NORMAL, "\n");
         }
 }
 
@@ -351,53 +578,64 @@ void lov_dump_user_lmm_join(struct lov_user_md_v1 *lum, char *path,
         if (obdindex != OBD_NOT_FOUND) {
                 for (i = 0; i < lumj->lmm_stripe_count; i++) {
                         if (obdindex == lumj->lmm_objects[i].l_ost_idx) {
-                                printf("%s\n", path);
+                                llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path);
                                 obdstripe = 1;
                                 break;
                         }
                 }
         } else if (!quiet) {
-                printf("%s\n", path);
+                llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path);
                 obdstripe = 1;
         }
 
         if (header && obdstripe == 1) {
-                printf("lmm_magic:          0x%08X\n",  lumj->lmm_magic);
-                printf("lmm_object_gr:      "LPX64"\n", lumj->lmm_object_gr);
-                printf("lmm_object_id:      "LPX64"\n", lumj->lmm_object_id);
-                printf("lmm_stripe_count:   %u\n", (int)lumj->lmm_stripe_count);
-                printf("lmm_stripe_size:    %u\n",      lumj->lmm_stripe_size);
-                printf("lmm_stripe_pattern: %x\n",      lumj->lmm_pattern);
-                printf("lmm_extent_count:   %x\n",      lumj->lmm_extent_count);
+                llapi_printf(LLAPI_MSG_NORMAL, "lmm_magic:          0x%08X\n",  
+                             lumj->lmm_magic);
+                llapi_printf(LLAPI_MSG_NORMAL, "lmm_object_gr:      "LPX64"\n", 
+                             lumj->lmm_object_gr);
+                llapi_printf(LLAPI_MSG_NORMAL, "lmm_object_id:      "LPX64"\n", 
+                             lumj->lmm_object_id);
+                llapi_printf(LLAPI_MSG_NORMAL, "lmm_stripe_count:   %u\n", 
+                             (int)lumj->lmm_stripe_count);
+                llapi_printf(LLAPI_MSG_NORMAL, "lmm_stripe_size:    %u\n",
+                             lumj->lmm_stripe_size);
+                llapi_printf(LLAPI_MSG_NORMAL, "lmm_stripe_pattern: %x\n",
+                             lumj->lmm_pattern);
+                llapi_printf(LLAPI_MSG_NORMAL, "lmm_extent_count:   %x\n",
+                             lumj->lmm_extent_count);
         }
 
         if (body) {
                 unsigned long long start = -1, end = 0;
                 if (!quiet && obdstripe == 1)
-                        printf("joined\tobdidx\t\t objid\t\tobjid\t\t group"
-                               "\t\tstart\t\tend\n");
+                        llapi_printf(LLAPI_MSG_NORMAL, 
+                                     "joined\tobdidx\t\t objid\t\tobjid\t\t group"
+                                     "\t\tstart\t\tend\n");
                 for (i = 0; i < lumj->lmm_stripe_count; i++) {
                         int idx = lumj->lmm_objects[i].l_ost_idx;
                         long long oid = lumj->lmm_objects[i].l_object_id;
                         long long gr = lumj->lmm_objects[i].l_object_gr;
                         if (obdindex == OBD_NOT_FOUND || obdindex == idx)
-                                printf("\t%6u\t%14llu\t%#13llx\t%14llu%s",
-                                       idx, oid, oid, gr,
-                                       obdindex == idx ? " *" : "");
+                                llapi_printf(LLAPI_MSG_NORMAL, 
+                                             "\t%6u\t%14llu\t%#13llx\t%14llu%s",
+                                             idx, oid, oid, gr,
+                                             obdindex == idx ? " *" : "");
                         if (start != lumj->lmm_objects[i].l_extent_start ||
                             end != lumj->lmm_objects[i].l_extent_end) {
                                 start = lumj->lmm_objects[i].l_extent_start;
-                                printf("\t%14llu", start);
+                                llapi_printf(LLAPI_MSG_NORMAL, "\t%14llu", start);
                                 end = lumj->lmm_objects[i].l_extent_end;
                                 if (end == (unsigned long long)-1)
-                                        printf("\t\tEOF\n");
+                                        llapi_printf(LLAPI_MSG_NORMAL, 
+                                                     "\t\tEOF\n");
                                 else
-                                        printf("\t\t%llu\n", end);
+                                        llapi_printf(LLAPI_MSG_NORMAL, 
+                                                     "\t\t%llu\n", end);
                         } else {
-                                printf("\t\t\t\t\n");
+                                llapi_printf(LLAPI_MSG_NORMAL, "\t\t\t\t\n");
                         }
                 }
-                printf("\n");
+                llapi_printf(LLAPI_MSG_NORMAL, "\n");
         }
 }
 
@@ -418,7 +656,8 @@ void llapi_lov_dump_user_lmm(struct find_param *param,
                                        (param->verbose || !param->obduuid));
                 break;
         default:
-                printf("unknown lmm_magic:  %#x (expecting %#x)\n",
+                llapi_printf(LLAPI_MSG_NORMAL, 
+                             "unknown lmm_magic:  %#x (expecting %#x)\n",
                        *(__u32 *)&param->lmd->lmd_lmm, LOV_USER_MAGIC_V1);
                 return;
         }
@@ -483,29 +722,55 @@ int llapi_file_lookup(int dirfd, const char *name)
 
         rc = obd_ioctl_pack(&data, &buf, sizeof(rawbuf));
         if (rc) {
-                fprintf(stderr,
-                        "error: IOC_MDC_LOOKUP pack failed for '%s': rc %d\n",
-                        name, rc);
+                llapi_err(LLAPI_MSG_ERROR,
+                          "error: IOC_MDC_LOOKUP pack failed for '%s': rc %d",
+                          name, rc);
                 return rc;
         }
 
         return ioctl(dirfd, IOC_MDC_LOOKUP, buf);
 }
 
-/* some 64bit libcs implement readdir64() by calling sys_getdents().  the
- * kernel's sys_getdents() doesn't return d_type.  */
-unsigned char handle_dt_unknown(char *path)
+int llapi_mds_getfileinfo(char *path, DIR *parent,
+                          struct lov_user_mds_data *lmd)
 {
-        int fd;
+        lstat_t *st = &lmd->lmd_st;
+        char *fname = strrchr(path, '/');
+        int ret = 0;
 
-        fd = open(path, O_DIRECTORY|O_RDONLY);
-        if (fd < 0) {
-                if (errno == ENOTDIR)
-                        return DT_REG; /* kind of a lie */
-                return DT_UNKNOWN;
+        if (parent == NULL)
+                return -EINVAL;
+
+        fname = (fname == NULL ? path : fname + 1);
+        /* retrieve needed file info */
+        strncpy((char *)lmd, fname, lov_mds_md_size(MAX_LOV_UUID_COUNT));
+        ret = ioctl(dirfd(parent), IOC_MDC_GETFILEINFO, (void *)lmd);
+
+        if (ret) {
+                if (errno == ENOTTY) {
+                        /* ioctl is not supported, it is not a lustre fs.
+                         * Do the regular lstat(2) instead. */
+                        ret = lstat_f(path, st);
+                        if (ret) {
+                                llapi_err(LLAPI_MSG_ERROR, 
+                                          "error: %s: lstat failed for %s",
+                                          __FUNCTION__, path);
+                                return ret;
+                        }
+                } else if (errno == ENOENT) {
+                        llapi_err(LLAPI_MSG_WARN, 
+                                  "warning: %s: %s does not exist", 
+                                  __FUNCTION__, path);
+                        return -ENOENT;
+                } else {
+                        llapi_err(LLAPI_MSG_ERROR, 
+                                  "error: %s: IOC_MDC_GETFILEINFO failed for %s",
+                                  __FUNCTION__, path);
+                        return ret;
+                }
         }
-        close(fd);
-        return DT_DIR;
+
+        return 0;
 }
 
 static DIR *opendir_parent(char *path)
@@ -527,7 +792,8 @@ static DIR *opendir_parent(char *path)
 
 static int llapi_semantic_traverse(char *path, int size, DIR *parent,
                                    semantic_func_t sem_init,
-                                   semantic_func_t sem_fini, void *data)
+                                   semantic_func_t sem_fini, void *data,
+                                   struct dirent64 *de)
 {
         struct dirent64 *dent;
         int len, ret;
@@ -538,8 +804,8 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent,
 
         d = opendir(path);
         if (!d && errno != ENOTDIR) {
-                fprintf(stderr, "%s: Failed to open '%s': %s.",
-                        __FUNCTION__, path, strerror(errno));
+                llapi_err(LLAPI_MSG_ERROR, "%s: Failed to open '%s'",
+                          __FUNCTION__, path);
                 return -EINVAL;
         } else if (!d && !parent) {
                 /* ENOTDIR. Open the parent dir. */
@@ -548,53 +814,63 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent,
                         GOTO(out, ret = -EINVAL);
         }
 
-        if (sem_init && (ret = sem_init(path, parent ?: p, d, data)))
+        if (sem_init && (ret = sem_init(path, parent ?: p, d, data, de)))
                 goto err;
 
         if (!d)
                 GOTO(out, ret = 0);
 
         while ((dent = readdir64(d)) != NULL) {
+                ((struct find_param *)data)->have_fileinfo = 0;
+
                 if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, ".."))
                         continue;
 
                 path[len] = 0;
                 if ((len + dent->d_reclen + 2) > size) {
-                        fprintf(stderr,
-                                "error: %s: string buffer is too small\n",
-                                __FUNCTION__);
+                        llapi_err(LLAPI_MSG_ERROR,
+                                  "error: %s: string buffer is too small",
+                                  __FUNCTION__);
                         break;
                 }
                 strcat(path, "/");
                 strcat(path, dent->d_name);
 
-                if (dent->d_type == DT_UNKNOWN)
-                        dent->d_type = handle_dt_unknown(path);
+                if (dent->d_type == DT_UNKNOWN) {
+                        lstat_t *st = &((struct find_param *)data)->lmd->lmd_st;
+
+                        ret = llapi_mds_getfileinfo(path, d,
+                                             ((struct find_param *)data)->lmd);
+                        if (ret == 0) {
+                                ((struct find_param *)data)->have_fileinfo = 1;
+                                dent->d_type = llapi_filetype_dir_table[st->st_mode &
+                                                                        S_IFMT];
+                        }
+                        if (ret == -ENOENT)
+                                continue;
+                }
 
                 switch (dent->d_type) {
                 case DT_UNKNOWN:
-                        fprintf(stderr, "error: %s: '%s' is UNKNOWN type %d",
-                                __FUNCTION__, dent->d_name, dent->d_type);
-                        /* If we cared we could stat the file to determine
-                         * type and continue on here, but we don't since we
-                         * know d_type should be valid for lustre and this
-                         * tool only makes sense for lustre filesystems. */
+                        llapi_err(LLAPI_MSG_ERROR, 
+                                  "error: %s: '%s' is UNKNOWN type %d",
+                                  __FUNCTION__, dent->d_name, dent->d_type);
                         break;
                 case DT_DIR:
                         ret = llapi_semantic_traverse(path, size, d, sem_init,
-                                                      sem_fini, data);
+                                                      sem_fini, data, dent);
                         if (ret < 0)
                                 goto out;
                         break;
                 default:
                         ret = 0;
                         if (sem_init) {
-                                ret = sem_init(path, d, NULL, data);
+                                ret = sem_init(path, d, NULL, data, dent);
                                 if (ret < 0)
                                         goto out;
                         }
                         if (sem_fini && ret == 0)
-                                sem_fini(path, d, NULL, data);
+                                sem_fini(path, d, NULL, data, dent);
                 }
         }
 
@@ -602,7 +878,7 @@ out:
         path[len] = 0;
 
         if (sem_fini)
-                sem_fini(path, parent, d, data);
+                sem_fini(path, parent, d, data, de);
 err:
         if (d)
                 closedir(d);
@@ -611,12 +887,12 @@ err:
         return ret;
 }
 
-/* Check if the file time matches 1 of the given criteria (e.g. --atime +/-N).
+/* Check if the value matches 1 of the given criteria (e.g. --atime +/-N).
  * @mds indicates if this is MDS timestamps and there are attributes on OSTs.
  *
  * The result is -1 if it does not match, 0 if not yet clear, 1 if matches.
- * The table bolow gives the answers for the specified parameters (time and
- * sign), 1st column is the answer for the MDS time, the 2nd is for the OST:
+ * The table bolow gives the answers for the specified parameters (value and
+ * sign), 1st column is the answer for the MDS value, the 2nd is for the OST:
  * --------------------------------------
  * 1 | file > limit; sign > 0 | -1 / -1 |
  * 2 | file = limit; sign > 0 |  ? /  1 |
@@ -628,18 +904,20 @@ err:
  * 8 | file = limit; sign < 0 |  ? / -1 |
  * 9 | file < limit; sign < 0 |  ? / -1 |
  * --------------------------------------
- * Note: 5th actually means that the file time stamp is within the interval
- * (limit - 24hours, limit]. */
-static int find_time_cmp(time_t file, time_t limit, int sign, int mds) {
+ * Note: 5th actually means that the value is within the interval
+ * (limit - margin, limit]. */
+static int find_value_cmp(unsigned int file, unsigned int limit, int sign,
+                          unsigned long long margin, int mds)
+{
         if (sign > 0) {
-                if (file <= limit)
+                if (file < limit)
                         return mds ? 0 : 1;
         }
 
         if (sign == 0) {
-                if (file <= limit && file + 24 * 60 * 60 > limit)
+                if (file <= limit && file + margin > limit)
                         return mds ? 0 : 1;
-                if (file + 24 * 60 * 60 <= limit)
+                if (file + margin <= limit)
                         return mds ? 0 : -1;
         }
 
@@ -667,16 +945,16 @@ static int find_time_check(lstat_t *st, struct find_param *param, int mds)
 
         /* Check if file is accepted. */
         if (param->atime) {
-                ret = find_time_cmp(st->st_atime, param->atime,
-                                    param->asign, mds);
+                ret = find_value_cmp(st->st_atime, param->atime,
+                                     param->asign, 24 * 60 * 60, mds);
                 if (ret < 0)
                         return ret;
                 rc = ret;
         }
 
         if (param->mtime) {
-                ret = find_time_cmp(st->st_mtime, param->mtime,
-                                    param->msign, mds);
+                ret = find_value_cmp(st->st_mtime, param->mtime,
+                                     param->msign, 24 * 60 * 60, mds);
                 if (ret < 0)
                         return ret;
 
@@ -687,8 +965,8 @@ static int find_time_check(lstat_t *st, struct find_param *param, int mds)
         }
 
         if (param->ctime) {
-                ret = find_time_cmp(st->st_ctime, param->ctime,
-                                    param->csign, mds);
+                ret = find_value_cmp(st->st_ctime, param->ctime,
+                                     param->csign, 24 * 60 * 60, mds);
                 if (ret < 0)
                         return ret;
 
@@ -701,35 +979,65 @@ static int find_time_check(lstat_t *st, struct find_param *param, int mds)
         return rc;
 }
 
-static int cb_find_init(char *path, DIR *parent, DIR *dir, void *data)
+static int cb_find_init(char *path, DIR *parent, DIR *dir,
+                        void *data, struct dirent64 *de)
 {
         struct find_param *param = (struct find_param *)data;
         int decision = 1; /* 1 is accepted; -1 is rejected. */
         lstat_t *st = &param->lmd->lmd_st;
         int lustre_fs = 1;
+        int checked_type = 0;
         int ret = 0;
 
         LASSERT(parent != NULL || dir != NULL);
 
         param->lmd->lmd_lmm.lmm_stripe_count = 0;
 
+        /* If a regular expression is presented, make the initial decision */
+        if (param->pattern != NULL) {
+                char *fname = strrchr(path, '/');
+                fname = (fname == NULL ? path : fname + 1);
+                ret = fnmatch(param->pattern, fname, 0);
+                if ((ret == FNM_NOMATCH && !param->exclude_pattern) ||
+                    (ret == 0 && param->exclude_pattern))
+                        goto decided;
+        }
+
+        /* See if we can check the file type from the dirent. */
+        if (param->type && de != NULL && de->d_type != DT_UNKNOWN &&
+            de->d_type < DT_MAX) {
+                checked_type = 1;
+                if (llapi_dir_filetype_table[de->d_type] == param->type) {
+                        if (param->exclude_type)
+                                goto decided;
+                } else {
+                        if (!param->exclude_type)
+                                goto decided;
+                }
+        }
+
+
         /* If a time or OST should be checked, the decision is not taken yet. */
-        if (param->atime || param->ctime || param->mtime || param->obduuid)
+        if (param->atime || param->ctime || param->mtime || param->obduuid ||
+            param->size)
                 decision = 0;
 
+        ret = 0;
         /* Request MDS for the stat info. */
-        if (!decision && dir) {
-                /* retrieve needed file info */
-                ret = ioctl(dirfd(dir), LL_IOC_MDC_GETINFO,
-                            (void *)param->lmd);
-        } else if (!decision && parent) {
-                char *fname = strrchr(path, '/');
-                fname = (fname == NULL ? path : fname + 1);
+        if (param->have_fileinfo == 0) {
+                if (dir) {
+                        /* retrieve needed file info */
+                        ret = ioctl(dirfd(dir), LL_IOC_MDC_GETINFO,
+                                    (void *)param->lmd);
+                } else {
+                        char *fname = strrchr(path, '/');
+                        fname = (fname == NULL ? path : fname + 1);
 
-                /* retrieve needed file info */
-                strncpy((char *)param->lmd, fname, param->lumlen);
-                ret = ioctl(dirfd(parent), IOC_MDC_GETFILEINFO,
-                           (void *)param->lmd);
+                        /* retrieve needed file info */
+                        strncpy((char *)param->lmd, fname, param->lumlen);
+                        ret = ioctl(dirfd(parent), IOC_MDC_GETFILEINFO,
+                                   (void *)param->lmd);
+                }
         }
 
         if (ret) {
@@ -739,18 +1047,34 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, void *data)
                         lustre_fs = 0;
                         ret = lstat_f(path, st);
                         if (ret) {
-                                err_msg("error: %s: lstat failed for %s",
-                                        __FUNCTION__, path);
+                                llapi_err(LLAPI_MSG_ERROR, 
+                                          "error: %s: lstat failed for %s",
+                                          __FUNCTION__, path);
                                 return ret;
                         }
+                } else if (errno == ENOENT) {
+                        llapi_err(LLAPI_MSG_WARN, 
+                                  "warning: %s: %s does not exist",
+                                  __FUNCTION__, path);
+                        goto decided;
                 } else {
-                        err_msg("error: %s: %s failed for %s", __FUNCTION__,
-                                dir ? "LL_IOC_MDC_GETINFO" :
-                                "IOC_MDC_GETFILEINFO", path);
+                        llapi_err(LLAPI_MSG_ERROR, "error: %s: %s failed for %s",
+                                  __FUNCTION__, dir ? "LL_IOC_MDC_GETINFO" :
+                                  "IOC_MDC_GETFILEINFO", path);
                         return ret;
                 }
         }
 
+        if (param->type && !checked_type) {
+                if ((st->st_mode & S_IFMT) == param->type) {
+                        if (param->exclude_type)
+                                goto decided;
+                } else {
+                        if (!param->exclude_type)
+                                goto decided;
+                }
+        }
+
         /* Prepare odb. */
         if (param->obduuid) {
                 if (lustre_fs && param->got_uuids &&
@@ -762,9 +1086,10 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, void *data)
                 }
 
                 if (lustre_fs && !param->got_uuids) {
-                        ret = setup_obd_uuids(dir ? dir : parent, path, param);
+                        ret = setup_obd_indexes(dir ? dir : parent, param);
                         if (ret)
                                 return ret;
+
                         param->st_dev = st->st_dev;
                 } else if (!lustre_fs && param->got_uuids) {
                         /* A lustre/non-lustre mount point is crossed. */
@@ -773,40 +1098,32 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, void *data)
                 }
         }
 
-        /* If a regular expression is presented, make the initial decision */
-        if (param->pattern != NULL) {
-                char *fname = strrchr(path, '/');
-                fname = (fname == NULL ? path : fname + 1);
-                ret = fnmatch(param->pattern, fname, 0);
-                if ((ret == FNM_NOMATCH && !param->exclude_pattern) ||
-                    (ret == 0 && param->exclude_pattern))
-                        decision = -1;
-        }
-
         /* If an OBD UUID is specified but no one matches, skip this file. */
         if (param->obduuid && param->obdindex == OBD_NOT_FOUND)
-                decision = -1;
+                goto decided;
 
         /* If a OST UUID is given, and some OST matches, check it here. */
-        if (decision != -1 && param->obdindex != OBD_NOT_FOUND) {
+        if (param->obdindex != OBD_NOT_FOUND) {
                 if (!S_ISREG(st->st_mode))
                         goto decided;
 
                 /* Only those files should be accepted, which have a
                  * stripe on the specified OST. */
                 if (!param->lmd->lmd_lmm.lmm_stripe_count) {
-                        decision = -1;
+                        goto decided;
                 } else {
-                        int i;
+                        int i, j;
                         for (i = 0;
                              i < param->lmd->lmd_lmm.lmm_stripe_count; i++) {
-                               if (param->obdindex ==
-                                   param->lmd->lmd_lmm.lmm_objects[i].l_ost_idx)
-                                        break;
+                                for (j = 0; j < param->num_obds; j++) {
+                                        if (param->obdindexes[j] ==
+                                            param->lmd->lmd_lmm.lmm_objects[i].l_ost_idx)
+                                                goto obd_matches;
+                                }
                         }
 
                         if (i == param->lmd->lmd_lmm.lmm_stripe_count)
-                                decision = -1;
+                                goto decided;
                 }
         }
 
@@ -820,11 +1137,12 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, void *data)
                 decision = find_time_check(st, param, for_mds);
         }
 
+obd_matches:
         /* If file still fits the request, ask osd for updated info.
            The regulat stat is almost of the same speed as some new
            'glimpse-size-ioctl'. */
-        if (!decision && param->lmd->lmd_lmm.lmm_stripe_count &&
-            S_ISREG(st->st_mode)) {
+        if (!decision && S_ISREG(st->st_mode) &&
+            (param->lmd->lmd_lmm.lmm_stripe_count || param->size)) {
                 if (param->obdindex != OBD_NOT_FOUND) {
                         /* Check whether the obd is active or not, if it is
                          * not active, just print the object affected by this
@@ -842,8 +1160,10 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, void *data)
                                 if (ret == -ENODATA || ret == -ENODEV 
                                     || ret == -EIO)
                                         errno = EIO;
-                                printf("obd_uuid: %s failed %s ",
-                                        param->obduuid->uuid, strerror(errno));
+                                llapi_printf(LLAPI_MSG_NORMAL, 
+                                             "obd_uuid: %s failed %s ",
+                                             param->obduuid->uuid, 
+                                             strerror(errno));
                                 goto print_path;
                         }
                 }
@@ -856,23 +1176,37 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, void *data)
                 }
 
                 if (ret) {
-                        fprintf(stderr, "%s: IOC_LOV_GETINFO on %s failed: "
-                                "%s.\n", __FUNCTION__, path, strerror(errno));
-                        return -EINVAL;
+                        if (errno == ENOENT) {
+                                llapi_err(LLAPI_MSG_ERROR, 
+                                          "warning: %s: %s does not exist",
+                                          __FUNCTION__, path);
+                                goto decided;
+                        } else {
+                                llapi_err(LLAPI_MSG_ERROR, 
+                                          "%s: IOC_LOV_GETINFO on %s failed",
+                                          __FUNCTION__, path);
+                                return ret;
+                        }
                 }
 
                 /* Check the time on osc. */
-                if (!decision)
-                        decision = find_time_check(st, param, 0);
+                decision = find_time_check(st, param, 0);
+                if (decision == -1)
+                        goto decided;
         }
 
+        if (param->size)
+                decision = find_value_cmp(st->st_size, param->size,
+                                          param->size_sign, param->size_units,
+                                          0);
+
 print_path:
         if (decision != -1) {
-                printf("%s", path);
+                llapi_printf(LLAPI_MSG_NORMAL, "%s", path);
                 if (param->zeroend)
-                        printf("%c", '\0');
+                        llapi_printf(LLAPI_MSG_NORMAL, "%c", '\0');
                 else
-                        printf("\n");
+                        llapi_printf(LLAPI_MSG_NORMAL, "\n");
         }
 
 decided:
@@ -884,7 +1218,8 @@ decided:
         return 0;
 }
 
-static int cb_common_fini(char *path, DIR *parent, DIR *d, void *data)
+static int cb_common_fini(char *path, DIR *parent, DIR *d, void *data,
+                          struct dirent64 *de)
 {
         struct find_param *param = (struct find_param *)data;
         param->depth--;
@@ -897,8 +1232,8 @@ int llapi_find(char *path, struct find_param *param)
         int ret, len = strlen(path);
 
         if (len > PATH_MAX) {
-                fprintf(stderr, "%s: Path name '%s' is too long.\n",
-                        __FUNCTION__, path);
+                llapi_err(LLAPI_MSG_ERROR, "%s: Path name '%s' is too long",
+                          __FUNCTION__, path);
                 return -EINVAL;
         }
 
@@ -916,14 +1251,15 @@ int llapi_find(char *path, struct find_param *param)
 
         strncpy(buf, path, PATH_MAX + 1);
         ret = llapi_semantic_traverse(buf, PATH_MAX + 1, NULL, cb_find_init,
-                                      cb_common_fini, param);
+                                      cb_common_fini, param, NULL);
 
         find_param_fini(param);
         free(buf);
         return ret < 0 ? ret : 0;
 }
 
-static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data)
+static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data,
+                        struct dirent64 *de)
 {
         struct find_param *param = (struct find_param *)data;
         int ret = 0;
@@ -932,7 +1268,7 @@ static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data)
 
         /* Prepare odb. */
         if (!param->got_uuids) {
-                ret = setup_obd_uuids(d ? d : parent, path, param);
+                ret = setup_obd_uuid(d ? d : parent, path, param);
                 if (ret)
                         return ret;
         }
@@ -952,15 +1288,23 @@ static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data)
         if (ret) {
                 if (errno == ENODATA) {
                         if (!param->obduuid && !param->quiet)
-                                printf("%s has no stripe info\n", path);
+                                llapi_printf(LLAPI_MSG_NORMAL, 
+                                             "%s has no stripe info\n", path);
                         goto out;
                 } else if (errno == ENOTTY) {
-                        fprintf(stderr, "%s: '%s' not on a Lustre fs?\n",
-                                __FUNCTION__, path);
+                        llapi_err(LLAPI_MSG_ERROR, 
+                                  "%s: '%s' not on a Lustre fs?",
+                                  __FUNCTION__, path);
+                } else if (errno == ENOENT) {
+                        llapi_err(LLAPI_MSG_WARN, 
+                                  "warning: %s: %s does not exist",
+                                  __FUNCTION__, path);
+                        goto out;
                 } else {
-                        err_msg("error: %s: %s failed for %s", __FUNCTION__,
-                                d ? "LL_IOC_LOV_GETSTRIPE" :
-                                "IOC_MDC_GETFILESTRIPE", path);
+                        llapi_err(LLAPI_MSG_ERROR, 
+                                  "error: %s: %s failed for %s",
+                                   __FUNCTION__, d ? "LL_IOC_LOV_GETSTRIPE" :
+                                  "IOC_MDC_GETFILESTRIPE", path);
                 }
 
                 return ret;
@@ -982,8 +1326,9 @@ int llapi_getstripe(char *path, struct find_param *param)
         int ret = 0, len = strlen(path);
 
         if (len > PATH_MAX) {
-                fprintf(stderr, "%s: Path name '%s' is too long.\n",
-                        __FUNCTION__, path);
+                llapi_err(LLAPI_MSG_ERROR, 
+                          "%s: Path name '%s' is too long",
+                          __FUNCTION__, path);
                 return -EINVAL;
         }
 
@@ -1001,7 +1346,7 @@ int llapi_getstripe(char *path, struct find_param *param)
 
         strncpy(buf, path, PATH_MAX + 1);
         ret = llapi_semantic_traverse(buf, PATH_MAX + 1, NULL, cb_getstripe,
-                                      cb_common_fini, param);
+                                      cb_common_fini, param, NULL);
         find_param_fini(param);
         free(buf);
         return ret < 0 ? ret : 0;
@@ -1027,7 +1372,8 @@ int llapi_obd_statfs(char *path, __u32 type, __u32 index,
         data.ioc_plen2 = sizeof(struct obd_uuid);
 
         if ((rc = obd_ioctl_pack(&data, &rawbuf, sizeof(raw))) != 0) {
-                fprintf(stderr, "llapi_obd_statfs: error packing ioctl data\n");
+                llapi_err(LLAPI_MSG_ERROR, 
+                          "llapi_obd_statfs: error packing ioctl data");
                 return rc;
         }
 
@@ -1037,7 +1383,8 @@ int llapi_obd_statfs(char *path, __u32 type, __u32 index,
 
         if (fd < 0) {
                 rc = errno ? -errno : -EBADF;
-                err_msg("error: %s: opening '%s'", __FUNCTION__, path);
+                llapi_err(LLAPI_MSG_ERROR, "error: %s: opening '%s'", 
+                          __FUNCTION__, path);
                 return rc;
         }
         rc = ioctl(fd, IOC_OBD_STATFS, (void *)rawbuf);
@@ -1063,7 +1410,7 @@ int llapi_ping(char *obd_type, char *obd_name)
         fd = open(path, O_WRONLY);
         if (fd < 0) {
                 rc = errno;
-                fprintf(stderr, "error opening %s: %s\n", path, strerror(errno));
+                llapi_err(LLAPI_MSG_ERROR, "error opening %s", path);
                 return rc;
         }
 
@@ -1083,8 +1430,7 @@ int llapi_target_iterate(int type_num, char **obd_type, void *args, llapi_cb_t c
 
         if (fp == NULL) {
                 rc = errno;
-                fprintf(stderr, "error: %s opening "DEVICES_LIST"\n",
-                        strerror(errno));
+                llapi_err(LLAPI_MSG_ERROR, "error: opening "DEVICES_LIST);
                 return rc;
         }
 
@@ -1131,9 +1477,9 @@ static void do_target_check(char *obd_type_name, char *obd_name,
 
         rc = llapi_ping(obd_type_name, obd_name);
         if (rc) {
-                err_msg("error: check '%s'", obd_name);
+                llapi_err(LLAPI_MSG_ERROR, "error: check '%s'", obd_name);
         } else {
-                printf("%s active.\n", obd_name);
+                llapi_printf(LLAPI_MSG_NORMAL, "%s active.\n", obd_name);
         }
 }
 
@@ -1172,15 +1518,15 @@ int llapi_catinfo(char *dir, char *keyword, char *node_name)
         root = opendir(dir);
         if (root == NULL) {
                 rc = errno;
-                err_msg("open %s failed", dir);
+                llapi_err(LLAPI_MSG_ERROR, "open %s failed", dir);
                 return rc;
         }
 
         rc = ioctl(dirfd(root), OBD_IOC_LLOG_CATINFO, buf);
         if (rc)
-                err_msg("ioctl OBD_IOC_CATINFO failed");
+                llapi_err(LLAPI_MSG_ERROR, "ioctl OBD_IOC_CATINFO failed");
         else
-                fprintf(stdout, "%s", data.ioc_pbuf1);
+                llapi_printf(LLAPI_MSG_NORMAL, "%s", data.ioc_pbuf1);
 
         closedir(root);
         return rc;
@@ -1206,7 +1552,7 @@ int llapi_quotacheck(char *mnt, int check_type)
 
         root = opendir(mnt);
         if (!root) {
-                err_msg("open %s failed", mnt);
+                llapi_err(LLAPI_MSG_ERROR, "open %s failed", mnt);
                 return -1;
         }
 
@@ -1224,7 +1570,7 @@ int llapi_poll_quotacheck(char *mnt, struct if_quotacheck *qchk)
 
         root = opendir(mnt);
         if (!root) {
-                err_msg("open %s failed", mnt);
+                llapi_err(LLAPI_MSG_ERROR, "open %s failed", mnt);
                 return -1;
         }
 
@@ -1248,7 +1594,7 @@ int llapi_quotactl(char *mnt, struct if_quotactl *qctl)
 
         root = opendir(mnt);
         if (!root) {
-                err_msg("open %s failed", mnt);
+                llapi_err(LLAPI_MSG_ERROR, "open %s failed", mnt);
                 return -1;
         }
 
@@ -1258,7 +1604,8 @@ int llapi_quotactl(char *mnt, struct if_quotactl *qctl)
         return rc;
 }
 
-static int cb_quotachown(char *path, DIR *parent, DIR *d, void *data)
+static int cb_quotachown(char *path, DIR *parent, DIR *d, void *data,
+                         struct dirent64 *de)
 {
         struct find_param *param = (struct find_param *)data;
         lstat_t *st;
@@ -1283,14 +1630,19 @@ static int cb_quotachown(char *path, DIR *parent, DIR *d, void *data)
         if (rc) {
                 if (errno == ENODATA) {
                         if (!param->obduuid && !param->quiet)
-                                fprintf(stderr, "%s has no stripe info\n",
-                                        path);
+                                llapi_err(LLAPI_MSG_ERROR, 
+                                          "%s has no stripe info", path);
+                        rc = 0;
+                } else if (errno == ENOENT) {
+                        llapi_err(LLAPI_MSG_ERROR, 
+                                  "warning: %s: %s does not exist",
+                                  __FUNCTION__, path);
                         rc = 0;
                 } else if (errno != EISDIR) {
                         rc = errno;
-                        err_msg("%s ioctl failed for %s.",
-                                d ? "LL_IOC_MDC_GETINFO" :
-                                "IOC_MDC_GETFILEINFO", path);
+                        llapi_err(LLAPI_MSG_ERROR, "%s ioctl failed for %s.",
+                                  d ? "LL_IOC_MDC_GETINFO" :
+                                  "IOC_MDC_GETFILEINFO", path);
                 }
                 return rc;
         }
@@ -1302,11 +1654,11 @@ static int cb_quotachown(char *path, DIR *parent, DIR *d, void *data)
          * invoke syscall directly. */
         rc = syscall(SYS_chown, path, -1, -1);
         if (rc)
-                err_msg("error: chown %s (%u,%u)", path);
+                llapi_err(LLAPI_MSG_ERROR,"error: chown %s (%u,%u)", path);
 
         rc = chmod(path, st->st_mode);
         if (rc)
-                err_msg("error: chmod %s (%hu)", path, st->st_mode);
+                llapi_err(LLAPI_MSG_ERROR,"error: chmod %s (%hu)", path, st->st_mode);
 
         return rc;
 }
@@ -1318,8 +1670,8 @@ int llapi_quotachown(char *path, int flag)
         int ret = 0, len = strlen(path);
 
         if (len > PATH_MAX) {
-                fprintf(stderr, "%s: Path name '%s' is too long.\n",
-                        __FUNCTION__, path);
+                llapi_err(LLAPI_MSG_ERROR, "%s: Path name '%s' is too long",
+                          __FUNCTION__, path);
                 return -EINVAL;
         }
 
@@ -1338,7 +1690,7 @@ int llapi_quotachown(char *path, int flag)
 
         strncpy(buf, path, PATH_MAX + 1);
         ret = llapi_semantic_traverse(buf, PATH_MAX + 1, NULL, cb_quotachown,
-                                      NULL, &param);
+                                      NULL, &param, NULL);
 out:
         find_param_fini(&param);
         free(buf);
@@ -1358,19 +1710,19 @@ int llapi_getfacl(char *fname, char *cmd)
 
         fd = open(fname, 0);
         if (fd == -1) {
-                err_msg("open %s failed", fname);
+                llapi_err(LLAPI_MSG_ERROR,"open %s failed", fname);
                 return -1;
         }
 
         rc = ioctl(fd, LL_IOC_GETFACL, &data);
         close(fd);
         if (errno == EBADE) {
-                fprintf(stderr, "Please use getfacl directly!\n");
+                llapi_err(LLAPI_MSG_ERROR, "Please use getfacl directly!");
                 rc = 1;
         } else if (rc) {
-                err_msg("getfacl %s failed", fname);
+                llapi_err(LLAPI_MSG_ERROR,"getfacl %s failed", fname);
         } else {
-                printf("%s", out);
+                llapi_printf(LLAPI_MSG_NORMAL, "%s", out);
         }
 
         return rc;
@@ -1389,22 +1741,22 @@ int llapi_setfacl(char *fname, char *cmd)
 
         fd = open(fname, 0);
         if (fd == -1) {
-                err_msg("open %s failed", fname);
+                llapi_err(LLAPI_MSG_ERROR,"open %s failed", fname);
                 return -1;
         }
 
         rc = ioctl(fd, LL_IOC_SETFACL, &data);
         close(fd);
         if (errno == EBADE) {
-                fprintf(stderr, "Please use setfacl directly!\n");
+                llapi_err(LLAPI_MSG_ERROR, "Please use setfacl directly!");
                 rc = 1;
         } else if (errno == EOPNOTSUPP) {
-                fprintf(stderr, "setfacl: %s: %s\n", fname, strerror(errno));
+                llapi_err(LLAPI_MSG_ERROR, "setfacl: %s: %s", fname);
                 rc = 1;
         } else if (rc) {
-                err_msg("setfacl %s failed", fname);
+                llapi_err(LLAPI_MSG_ERROR,"setfacl %s failed", fname);
         } else {
-                printf("%s", out);
+                llapi_printf(LLAPI_MSG_NORMAL, "%s", out);
         }
 
         return rc;