Whamcloud - gitweb
use special macro for print time_t, cleanup in includes.
[fs/lustre-release.git] / lustre / utils / liblustreapi.c
index 89ca95e..b9328e5 100644 (file)
@@ -96,15 +96,51 @@ static const int S_IFMAX = DT_DOOR;
 static const int S_IFMAX = DT_SOCK;
 #endif
 
-static void err_msg(char *fmt, ...)
+/* 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,
@@ -174,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;
         }
 
@@ -183,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;
         }
 
@@ -222,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) {
@@ -249,7 +292,7 @@ int llapi_file_create(const char *name, unsigned long stripe_size,
 }
 
 typedef int (semantic_func_t)(char *path, DIR *parent, DIR *d,
-                              void *data, struct dirent64 *de);
+                              void *data, cfs_dirent_t *de);
 
 #define MAX_LOV_UUID_COUNT      max(LOV_MAX_STRIPE_COUNT, 1000)
 #define OBD_NOT_FOUND           (-1)
@@ -258,8 +301,9 @@ 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;
         }
 
@@ -295,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;
         }
 
@@ -305,7 +349,7 @@ 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;
         }
 
@@ -340,7 +384,8 @@ static int setup_obd_uuid(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;
                 }
@@ -355,12 +400,12 @@ static int setup_obd_uuid(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)
@@ -374,7 +419,7 @@ static int setup_obd_uuid(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;
@@ -383,8 +428,9 @@ static int setup_obd_uuid(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;
         }
 
@@ -420,7 +466,7 @@ retry_get_uuids:
                                 ret = -ENOMEM;
                 }
 
-                fprintf(stderr, "get ost uuid failed: %s\n", strerror(errno));
+                llapi_err(LLAPI_MSG_ERROR, "get ost uuid failed");
                 return ret;
         }
 
@@ -459,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");
         }
 }
 
@@ -519,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");
         }
 }
 
@@ -586,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;
         }
@@ -651,9 +722,9 @@ 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;
         }
 
@@ -681,17 +752,20 @@ int llapi_mds_getfileinfo(char *path, DIR *parent,
                          * Do the regular lstat(2) instead. */
                         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) {
-                        err_msg("warning: %s: %s does not exist", __FUNCTION__,
-                                path);
+                        llapi_err(LLAPI_MSG_WARN, 
+                                  "warning: %s: %s does not exist", 
+                                  __FUNCTION__, path);
                         return -ENOENT;
                 } else {
-                        err_msg("error: %s: IOC_MDC_GETFILEINFO failed for %s",
-                                __FUNCTION__, path);
+                        llapi_err(LLAPI_MSG_ERROR, 
+                                  "error: %s: IOC_MDC_GETFILEINFO failed for %s",
+                                  __FUNCTION__, path);
                         return ret;
                 }
         }
@@ -719,9 +793,9 @@ 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,
-                                   struct dirent64 *de)
+                                   cfs_dirent_t *de)
 {
-        struct dirent64 *dent;
+        cfs_dirent_t *dent;
         int len, ret;
         DIR *d, *p = NULL;
 
@@ -730,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. */
@@ -754,9 +828,9 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent,
 
                 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, "/");
@@ -778,8 +852,9 @@ static int llapi_semantic_traverse(char *path, int size, DIR *parent,
 
                 switch (dent->d_type) {
                 case DT_UNKNOWN:
-                        fprintf(stderr, "error: %s: '%s' is UNKNOWN type %d",
-                                __FUNCTION__, dent->d_name, dent->d_type);
+                        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,
@@ -905,7 +980,7 @@ static int find_time_check(lstat_t *st, struct find_param *param, int mds)
 }
 
 static int cb_find_init(char *path, DIR *parent, DIR *dir,
-                        void *data, struct dirent64 *de)
+                        void *data, cfs_dirent_t *de)
 {
         struct find_param *param = (struct find_param *)data;
         int decision = 1; /* 1 is accepted; -1 is rejected. */
@@ -972,18 +1047,20 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir,
                         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) {
-                        err_msg("warning: %s: %s does not exist",
-                                __FUNCTION__, path);
+                        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;
                 }
         }
@@ -1083,8 +1160,10 @@ obd_matches:
                                 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;
                         }
                 }
@@ -1098,12 +1177,14 @@ obd_matches:
 
                 if (ret) {
                         if (errno == ENOENT) {
-                                err_msg("warning: %s: %s does not exist",
-                                        __FUNCTION__, path);
+                                llapi_err(LLAPI_MSG_ERROR, 
+                                          "warning: %s: %s does not exist",
+                                          __FUNCTION__, path);
                                 goto decided;
                         } else {
-                                fprintf(stderr, "%s: IOC_LOV_GETINFO on %s failed: "
-                                        "%s.\n", __FUNCTION__, path, strerror(errno));
+                                llapi_err(LLAPI_MSG_ERROR, 
+                                          "%s: IOC_LOV_GETINFO on %s failed",
+                                          __FUNCTION__, path);
                                 return ret;
                         }
                 }
@@ -1121,11 +1202,11 @@ obd_matches:
 
 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:
@@ -1138,7 +1219,7 @@ decided:
 }
 
 static int cb_common_fini(char *path, DIR *parent, DIR *d, void *data,
-                          struct dirent64 *de)
+                          cfs_dirent_t *de)
 {
         struct find_param *param = (struct find_param *)data;
         param->depth--;
@@ -1151,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;
         }
 
@@ -1178,7 +1259,7 @@ int llapi_find(char *path, struct find_param *param)
 }
 
 static int cb_getstripe(char *path, DIR *parent, DIR *d, void *data,
-                        struct dirent64 *de)
+                        cfs_dirent_t *de)
 {
         struct find_param *param = (struct find_param *)data;
         int ret = 0;
@@ -1207,19 +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) {
-                        err_msg("warning: %s: %s does not exist",
-                                __FUNCTION__, path);
+                        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;
@@ -1241,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;
         }
 
@@ -1286,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;
         }
 
@@ -1296,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);
@@ -1322,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;
         }
 
@@ -1342,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;
         }
 
@@ -1390,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);
         }
 }
 
@@ -1431,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;
@@ -1465,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;
         }
 
@@ -1483,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;
         }
 
@@ -1507,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;
         }
 
@@ -1518,7 +1605,7 @@ int llapi_quotactl(char *mnt, struct if_quotactl *qctl)
 }
 
 static int cb_quotachown(char *path, DIR *parent, DIR *d, void *data,
-                         struct dirent64 *de)
+                         cfs_dirent_t *de)
 {
         struct find_param *param = (struct find_param *)data;
         lstat_t *st;
@@ -1543,18 +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) {
-                        err_msg("warning: %s: %s does not exist",
-                                __FUNCTION__, path);
+                        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;
         }
@@ -1566,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;
 }
@@ -1582,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;
         }
 
@@ -1609,67 +1697,293 @@ out:
         return ret;
 }
 
-int llapi_getfacl(char *fname, char *cmd)
+#include <pwd.h>
+#include <grp.h>
+#include <mntent.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <ctype.h>
+
+static int rmtacl_notify(int ops)
 {
-        struct rmtacl_ioctl_data data;
-        char out[RMTACL_SIZE_MAX] = "";
-        int fd, rc;
-
-        data.cmd = cmd;
-        data.cmd_len = strlen(cmd) + 1;
-        data.res = out;
-        data.res_len = sizeof(out);
-
-        fd = open(fname, 0);
-        if (fd == -1) {
-                err_msg("open %s failed", fname);
+        FILE *fp;
+        struct mntent *mnt;
+        int found = 0, fd, rc;
+
+        fp = setmntent(MOUNTED, "r");
+        if (fp == NULL) {
+                perror("setmntent");
                 return -1;
         }
 
-        rc = ioctl(fd, LL_IOC_GETFACL, &data);
-        close(fd);
-        if (errno == EBADE) {
-                fprintf(stderr, "Please use getfacl directly!\n");
-                rc = 1;
-        } else if (rc) {
-                err_msg("getfacl %s failed", fname);
+        while (1) {
+                mnt = getmntent(fp);
+                if (!mnt)
+                        break;
+
+                if (!llapi_is_lustre_mnt(mnt))
+                        continue;
+
+                fd = open(mnt->mnt_dir, O_RDONLY | O_DIRECTORY);
+                if (fd < 0) {
+                        perror("open");
+                        return -1;
+                }
+
+                rc = ioctl(fd, LL_IOC_RMTACL, ops);
+                if (rc < 0) {
+                        perror("ioctl");
+                return -1;
+        }
+
+                found++;
+        }
+        endmntent(fp);
+        return found;
+}
+
+static char *next_token(char *p, int div)
+{
+        if (p == NULL)
+                return NULL;
+
+        if (div)
+                while (*p && *p != ':' && !isspace(*p))
+                        p++;
+        else
+                while (*p == ':' || isspace(*p))
+                        p++;
+
+        return *p ? p : NULL;
+}
+
+static int rmtacl_name2id(char *name, int is_user)
+{
+        if (is_user) {
+                struct passwd *pw;
+
+                if ((pw = getpwnam(name)) == NULL)
+                        return INVALID_ID;
+                else
+                        return (int)(pw->pw_uid);
         } else {
-                printf("%s", out);
+                struct group *gr;
+
+                if ((gr = getgrnam(name)) == NULL)
+                        return INVALID_ID;
+                else
+                        return (int)(gr->gr_gid);
         }
+}
 
-        return rc;
+static int isodigit(int c)
+{
+        return (c >= '0' && c <= '7') ? 1 : 0;
+}
+
+/*
+ * Whether the name is just digits string (uid/gid) already or not.
+ * Return value:
+ * 1: str is id
+ * 0: str is not id
+ */
+static int str_is_id(char *str)
+{
+        if (str == NULL)
+                return 0;
+
+        if (*str == '0') {
+                str++;
+                if (*str == 'x' || *str == 'X') { /* for Hex. */
+                        if (!isxdigit(*(++str)))
+                                return 0;
+
+                        while (isxdigit(*(++str)));
+                } else if (isodigit(*str)) { /* for Oct. */
+                        while (isodigit(*(++str)));
+                }
+        } else if (isdigit(*str)) { /* for Dec. */
+                while (isdigit(*(++str)));
+        }
+
+        return (*str == 0) ? 1 : 0;
 }
 
-int llapi_setfacl(char *fname, char *cmd)
+typedef struct {
+        char *name;
+        int   length;
+        int   is_user;
+        int   next_token;
+} rmtacl_name_t;
+
+#define RMTACL_OPTNAME(name) name, sizeof(name) - 1
+
+static rmtacl_name_t rmtacl_namelist[] = {
+        { RMTACL_OPTNAME("user:"),            1,      0 },
+        { RMTACL_OPTNAME("group:"),           0,      0 },
+        { RMTACL_OPTNAME("default:user:"),    1,      0 },
+        { RMTACL_OPTNAME("default:group:"),   0,      0 },
+        /* for --tabular option */
+        { RMTACL_OPTNAME("user"),             1,      1 },
+        { RMTACL_OPTNAME("group"),            0,      1 },
+        { 0 }
+};
+
+static int rgetfacl_output(char *str)
 {
-        struct rmtacl_ioctl_data data;
-        char out[RMTACL_SIZE_MAX] = "";
-        int fd, rc;
-
-        data.cmd = cmd;
-        data.cmd_len = strlen(cmd) + 1;
-        data.res = out;
-        data.res_len = sizeof(out);
-
-        fd = open(fname, 0);
-        if (fd == -1) {
-                err_msg("open %s failed", fname);
+        char *start = NULL, *end = NULL;
+        int is_user = 0, n, id;
+        char c;
+        rmtacl_name_t *rn;
+
+        if (str == NULL)
                 return -1;
+
+        for (rn = rmtacl_namelist; rn->name; rn++) {
+                if(strncmp(str, rn->name, rn->length) == 0) {
+                        if (!rn->next_token)
+                                start = str + rn->length;
+                        else
+                                start = next_token(str + rn->length, 0);
+                        is_user = rn->is_user;
+                        break;
+                }
         }
 
-        rc = ioctl(fd, LL_IOC_SETFACL, &data);
-        close(fd);
-        if (errno == EBADE) {
-                fprintf(stderr, "Please use setfacl directly!\n");
-                rc = 1;
-        } else if (errno == EOPNOTSUPP) {
-                fprintf(stderr, "setfacl: %s: %s\n", fname, strerror(errno));
-                rc = 1;
-        } else if (rc) {
-                err_msg("setfacl %s failed", fname);
+        end = next_token(start, 1);
+        if (end == NULL || start == end) {
+                n = printf("%s", str);
+                return n;
+        }
+
+        c = *end;
+        *end = 0;
+        id = rmtacl_name2id(start, is_user);
+        if (id == INVALID_ID) {
+                if (str_is_id(start)) {
+                        *end = c;
+                        n = printf("%s", str);
+                } else
+                        return -1;
+        } else if ((id == NOBODY_UID && is_user) ||
+                   (id == NOBODY_GID && !is_user)) {
+                *end = c;
+                n = printf("%s", str);
         } else {
-                printf("%s", out);
+                *end = c;
+                *start = 0;
+                n = printf("%s%d%s", str, id, end);
         }
+        return n;
+}
 
-        return rc;
+static int child_status(int status)
+{
+        return WIFEXITED(status) ? WEXITSTATUS(status) : -1;
+}
+
+static int do_rmtacl(int argc, char *argv[], int ops, int (output_func)(char *))
+{
+        pid_t pid = 0;
+        int fd[2], status;
+        FILE *fp;
+        char buf[PIPE_BUF];
+
+        if (output_func) {
+                if (pipe(fd) < 0) {
+                        perror("pipe");
+                        return -1;
+                }
+
+                if ((pid = fork()) < 0) {
+                        perror("fork");
+                        close(fd[0]);
+                        close(fd[1]);
+                        return -1;
+                } else if (!pid) {
+                        /* child process redirects its output. */
+                        close(fd[0]);
+                        close(1);
+                        if (dup2(fd[1], 1) < 0) {
+                                perror("dup2");
+                                close(fd[1]);
+                                return -1;
+                        }
+                } else {
+                        close(fd[1]);
+                }
+        }
+
+        if (!pid) {
+                status = rmtacl_notify(ops);
+                if (status < 0)
+                        return -1;
+
+                exit(execvp(argv[0], argv));
+        }
+
+        /* the following is parent process */
+        if ((fp = fdopen(fd[0], "r")) == NULL) {
+                perror("fdopen");
+                kill(pid, SIGKILL);
+                close(fd[0]);
+                return -1;
+        }
+
+        while (fgets(buf, PIPE_BUF, fp) != NULL) {
+                if (output_func(buf) < 0)
+                        fprintf(stderr, "WARNING: unexpected error!\n[%s]\n",
+                                buf);
+        }
+        fclose(fp);
+        close(fd[0]);
+
+        if (waitpid(pid, &status, 0) < 0) {
+                perror("waitpid");
+                return -1;
+        }
+
+        return child_status(status);
+}
+
+int llapi_lsetfacl(int argc, char *argv[])
+{
+        return do_rmtacl(argc, argv, RMT_LSETFACL, NULL);
+}
+
+int llapi_lgetfacl(int argc, char *argv[])
+{
+        return do_rmtacl(argc, argv, RMT_LGETFACL, NULL);
+}
+
+int llapi_rsetfacl(int argc, char *argv[])
+{
+        return do_rmtacl(argc, argv, RMT_RSETFACL, NULL);
+}
+
+int llapi_rgetfacl(int argc, char *argv[])
+{
+        return do_rmtacl(argc, argv, RMT_RGETFACL, rgetfacl_output);
+}
+
+int llapi_cp(int argc, char *argv[])
+{
+        int rc;
+
+        rc = rmtacl_notify(RMT_RSETFACL);
+        if (rc < 0)
+                return -1;
+
+        exit(execvp(argv[0], argv));
+}
+
+int llapi_ls(int argc, char *argv[])
+{
+        int rc;
+
+        rc = rmtacl_notify(RMT_LGETFACL);
+        if (rc < 0)
+                return -1;
+
+        exit(execvp(argv[0], argv));
 }