Whamcloud - gitweb
b=12797
[fs/lustre-release.git] / lustre / utils / liblustreapi.c
index 406c629..a6ddb9d 100644 (file)
@@ -23,7 +23,6 @@
  *
  */
 
-
 /* for O_DIRECTORY */
 #define _GNU_SOURCE
 
@@ -50,9 +49,8 @@
 #include <unistd.h>
 #endif
 
-#include <lnet/lnetctl.h>
-
 #include <liblustre.h>
+#include <lnet/lnetctl.h>
 #include <obd.h>
 #include <lustre_lib.h>
 #include <obd_lov.h>
@@ -69,16 +67,17 @@ static void err_msg(char *fmt, ...)
         fprintf(stderr, ": %s (%d)\n", strerror(tmp_errno), tmp_errno);
 }
 
-int llapi_file_create(const char *name, unsigned long stripe_size, int stripe_offset,
-                      int stripe_count, int stripe_pattern)
+int llapi_file_open(const char *name, int flags, int mode,
+                    unsigned long stripe_size, int stripe_offset,
+                    int stripe_count, int stripe_pattern)
 {
         struct lov_user_md lum = { 0 };
         int fd, rc = 0;
         int isdir = 0;
         int page_size;
 
-        fd = open(name, O_CREAT | O_RDWR | O_LOV_DELAY_CREATE, 0644);
-        if (errno == EISDIR) {
+        fd = open(name, flags | O_LOV_DELAY_CREATE, mode);
+        if (fd < 0 && errno == EISDIR) {
                 fd = open(name, O_DIRECTORY | O_RDONLY);
                 isdir++;
         }
@@ -133,17 +132,30 @@ int llapi_file_create(const char *name, unsigned long stripe_size, int stripe_of
                 if (errno != EEXIST && errno != EALREADY)
                         errmsg = strerror(errno);
 
-                rc = -errno;
                 fprintf(stderr, "error on ioctl "LPX64" for '%s' (%d): %s\n",
                         (__u64)LL_IOC_LOV_SETSTRIPE, name, fd, errmsg);
         }
 out:
-        if (close(fd) < 0) {
-                if (rc == 0)
-                        rc = -errno;
-                err_msg("error on close for '%s' (%d)", name, fd);
+        if (rc) {
+                close(fd);
+                fd = rc;
         }
-        return rc;
+
+        return fd;
+}
+
+int llapi_file_create(const char *name, unsigned long stripe_size,
+                      int stripe_offset, int stripe_count, int stripe_pattern)
+{
+        int fd;
+
+        fd = llapi_file_open(name, O_CREAT | O_WRONLY, 0644, stripe_size,
+                             stripe_offset, stripe_count, stripe_pattern);
+        if (fd < 0)
+                return fd;
+
+        close(fd);
+        return 0;
 }
 
 typedef int (semantic_func_t)(char *path, DIR *parent, DIR *d, void *data);
@@ -513,7 +525,7 @@ static DIR *opendir_parent(char *path)
         return parent;
 }
 
-static int llapi_semantic_traverse(char *path, DIR *parent,
+static int llapi_semantic_traverse(char *path, int size, DIR *parent,
                                    semantic_func_t sem_init,
                                    semantic_func_t sem_fini, void *data)
 {
@@ -547,6 +559,12 @@ static int llapi_semantic_traverse(char *path, DIR *parent,
                         continue;
 
                 path[len] = 0;
+                if ((len + dent->d_reclen + 2) > size) {
+                        fprintf(stderr,
+                                "error: %s: string buffer is too small\n",
+                                __FUNCTION__);
+                        break;
+                }
                 strcat(path, "/");
                 strcat(path, dent->d_name);
 
@@ -563,7 +581,7 @@ static int llapi_semantic_traverse(char *path, DIR *parent,
                          * tool only makes sense for lustre filesystems. */
                         break;
                 case DT_DIR:
-                        ret = llapi_semantic_traverse(path, d, sem_init,
+                        ret = llapi_semantic_traverse(path, size, d, sem_init,
                                                       sem_fini, data);
                         if (ret < 0)
                                 goto out;
@@ -770,10 +788,12 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, void *data)
                 decision = -1;
 
         /* If a OST UUID is given, and some OST matches, check it here. */
-        if (decision != -1 && param->obdindex != OBD_NOT_FOUND &&
-            S_ISREG(st->st_mode)) {
-                /* Only those files should be accepted, which have a strip on
-                 * the specified OST. */
+        if (decision != -1 && 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;
                 } else {
@@ -855,6 +875,7 @@ print_path:
                         printf("\n");
         }
 
+decided:
         /* Do not get down anymore? */
         if (param->depth == param->maxdepth)
                 return 1;
@@ -872,21 +893,33 @@ static int cb_common_fini(char *path, DIR *parent, DIR *d, void *data)
 
 int llapi_find(char *path, struct find_param *param)
 {
-        char buf[PATH_MAX + 1];
-        int ret;
+        char *buf;
+        int ret, len = strlen(path);
+
+        if (len > PATH_MAX) {
+                fprintf(stderr, "%s: Path name '%s' is too long.\n",
+                        __FUNCTION__, path);
+                return -EINVAL;
+        }
+
+        buf = (char *)malloc(PATH_MAX + 1);
+        if (!buf)
+                return -ENOMEM;
 
         ret = common_param_init(param);
-        if (ret)
+        if (ret) {
+                free(buf);
                 return ret;
+        }
 
         param->depth = 0;
-        strncpy(buf, path, strlen(path));
-        buf[strlen(path)] = '\0';
 
-        ret = llapi_semantic_traverse(buf, NULL, cb_find_init,
+        strncpy(buf, path, PATH_MAX + 1);
+        ret = llapi_semantic_traverse(buf, PATH_MAX + 1, NULL, cb_find_init,
                                       cb_common_fini, param);
 
         find_param_fini(param);
+        free(buf);
         return ret < 0 ? ret : 0;
 }
 
@@ -945,16 +978,32 @@ out:
 
 int llapi_getstripe(char *path, struct find_param *param)
 {
-        int ret = 0;
+        char *buf;
+        int ret = 0, len = strlen(path);
+
+        if (len > PATH_MAX) {
+                fprintf(stderr, "%s: Path name '%s' is too long.\n",
+                        __FUNCTION__, path);
+                return -EINVAL;
+        }
+
+        buf = (char *)malloc(PATH_MAX + 1);
+        if (!buf)
+                return -ENOMEM;
 
         ret = common_param_init(param);
-        if (ret)
+        if (ret) {
+                free(buf);
                 return ret;
+        }
 
         param->depth = 0;
-        ret = llapi_semantic_traverse(path, NULL, cb_getstripe,
+
+        strncpy(buf, path, PATH_MAX + 1);
+        ret = llapi_semantic_traverse(buf, PATH_MAX + 1, NULL, cb_getstripe,
                                       cb_common_fini, param);
         find_param_fini(param);
+        free(buf);
         return ret < 0 ? ret : 0;
 }
 
@@ -1265,7 +1314,18 @@ static int cb_quotachown(char *path, DIR *parent, DIR *d, void *data)
 int llapi_quotachown(char *path, int flag)
 {
         struct find_param param;
-        int ret = 0;
+        char *buf;
+        int ret = 0, len = strlen(path);
+
+        if (len > PATH_MAX) {
+                fprintf(stderr, "%s: Path name '%s' is too long.\n",
+                        __FUNCTION__, path);
+                return -EINVAL;
+        }
+
+        buf = (char *)malloc(PATH_MAX + 1);
+        if (!buf)
+                return -ENOMEM;
 
         memset(&param, 0, sizeof(param));
         param.recursive = 1;
@@ -1276,10 +1336,12 @@ int llapi_quotachown(char *path, int flag)
         if (ret)
                 goto out;
 
-        ret = llapi_semantic_traverse(path, NULL, cb_quotachown,
+        strncpy(buf, path, PATH_MAX + 1);
+        ret = llapi_semantic_traverse(buf, PATH_MAX + 1, NULL, cb_quotachown,
                                       NULL, &param);
 out:
         find_param_fini(&param);
+        free(buf);
         return ret;
 }