Whamcloud - gitweb
Branch HEAD
[fs/lustre-release.git] / lustre / utils / liblustreapi.c
index 553ca34..c5e410e 100644 (file)
@@ -55,7 +55,6 @@
 #include <liblustre.h>
 #include <obd.h>
 #include <lustre_lib.h>
-#include <lustre/liblustreapi.h>
 #include <obd_lov.h>
 #include <lustre/liblustreapi.h>
 
@@ -70,23 +69,24 @@ 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++;
         }
 
         if (fd < 0) {
                 rc = -errno;
-                err_msg("unable to open '%s'",name);
+                err_msg("unable to open '%s'", name);
                 return rc;
         }
 
@@ -99,25 +99,25 @@ int llapi_file_create(const char *name, unsigned long stripe_size,
                         "expected (%u).\n", 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);
-                errno = rc = -EINVAL;
                 goto out;
         }
         if (stripe_offset < -1 || stripe_offset > MAX_OBD_DEVICES) {
-                err_msg("error: bad stripe offset %d", stripe_offset);
                 errno = rc = -EINVAL;
+                err_msg("error: bad stripe offset %d", stripe_offset);
                 goto out;
         }
         if (stripe_count < -1 || stripe_count > LOV_MAX_STRIPE_COUNT) {
-                err_msg("error: bad stripe count %d", stripe_count);
                 errno = rc = -EINVAL;
+                err_msg("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);
-                errno = rc = -EINVAL;
                 goto out;
         }
 
@@ -139,12 +139,26 @@ int llapi_file_create(const char *name, unsigned long stripe_size,
                         (__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);
@@ -174,57 +188,37 @@ static void find_param_fini(struct find_param *param)
 
 int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count)
 {
-        struct obd_ioctl_data data = { 0, };
-        struct lov_desc desc = { 0, };
-        char *buf = NULL;
-        int max_ost_count, rc;
-        __u32 *obdgens;
-
-        max_ost_count = (OBD_MAX_IOCTL_BUFFER - size_round(sizeof(data)) -
-                         size_round(sizeof(desc))) /
-                        (sizeof(*uuidp) + sizeof(*obdgens));
-        if (max_ost_count > *ost_count)
-                max_ost_count = *ost_count;
-
-        obdgens = malloc(size_round(max_ost_count * sizeof(*obdgens)));
-        if (!obdgens) {
-                err_msg("error: %d generation #'s", max_ost_count);
-                return(-ENOMEM);
-        }
-
-        data.ioc_inllen1 = sizeof(desc);
-        data.ioc_inlbuf1 = (char *)&desc;
-        data.ioc_inllen2 = size_round(max_ost_count * sizeof(*uuidp));
-        data.ioc_inlbuf2 = (char *)uuidp;
-        data.ioc_inllen3 = size_round(max_ost_count * sizeof(*obdgens));
-        data.ioc_inlbuf3 = (char *)obdgens;
-
-        desc.ld_tgt_count = max_ost_count;
-
-        if (obd_ioctl_pack(&data, &buf, OBD_MAX_IOCTL_BUFFER)) {
-                fprintf(stderr, "error: %s: internal packing error\n",
-                        __FUNCTION__);
-                rc = EINVAL;
-                goto out;
-        }
+        char lov_name[sizeof(struct obd_uuid)];
+        char buf[1024];
+        FILE *fp;
+        int rc = 0, index = 0;
 
-        rc = ioctl(fd, OBD_IOC_LOV_GET_CONFIG, buf);
+        /* Get the lov name */
+        rc = ioctl(fd, OBD_IOC_GETNAME, (void *) lov_name);
         if (rc) {
                 rc = errno;
-                err_msg("error: %s: getting LOV config", __FUNCTION__);
-                goto out;
+                err_msg("error: can't get lov name.");
+                return rc;
         }
 
-        if (obd_ioctl_unpack(&data, buf, OBD_MAX_IOCTL_BUFFER)) {
-                rc = errno = EINVAL;
-                err_msg("error: %s: internal ioctl unpack", __FUNCTION__);
-                goto out;
+        /* Now get the ost uuids from /proc */
+        snprintf(buf, sizeof(buf), "/proc/fs/lustre/lov/%s/target_obd",
+                 lov_name);
+        fp = fopen(buf, "r");
+        if (fp == NULL) {
+                rc = errno;
+                err_msg("error: opening '%s'", buf);
+                return rc;
         }
 
-        *ost_count = desc.ld_tgt_count;
-out:
-        free(buf);
-        free(obdgens);
+        while ((fgets(buf, sizeof(buf), fp) != NULL) && index < *ost_count) {
+                if (sscanf(buf, "%d: %s", &index, uuidp[index].uuid) < 2)
+                        break;
+                index++;
+        }
+
+        fclose(fp);
+        *ost_count = index;
 
         return rc;
 }
@@ -791,7 +785,8 @@ 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) {
+        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 (!param->lmd->lmd_lmm.lmm_stripe_count) {
@@ -814,14 +809,39 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, void *data)
         if (!decision) {
                 int for_mds;
 
-                for_mds = lustre_fs ? param->lmd->lmd_lmm.lmm_stripe_count : 0;
+                for_mds = lustre_fs ? (S_ISREG(st->st_mode) &&
+                                       param->lmd->lmd_lmm.lmm_stripe_count)
+                                    : 0;
                 decision = find_time_check(st, param, for_mds);
         }
 
         /* 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) {
+        if (!decision && param->lmd->lmd_lmm.lmm_stripe_count &&
+            S_ISREG(st->st_mode)) {
+                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
+                         * failed ost 
+                         * */
+                        struct obd_statfs stat_buf;
+                        struct obd_uuid uuid_buf;
+
+                        memset(&stat_buf, 0, sizeof(struct obd_statfs));
+                        memset(&uuid_buf, 0, sizeof(struct obd_uuid));
+                        ret = llapi_obd_statfs(path, LL_STATFS_LOV,
+                                               param->obdindex, &stat_buf, 
+                                               &uuid_buf);
+                        if (ret) {
+                                if (ret == -ENODATA || ret == -ENODEV 
+                                    || ret == -EIO)
+                                        errno = EIO;
+                                printf("obd_uuid: %s failed %s ",
+                                        param->obduuid->uuid, strerror(errno));
+                                goto print_path;
+                        }
+                }
                 if (dir) {
                         ret = ioctl(dirfd(dir), IOC_LOV_GETINFO,
                                     (void *)param->lmd);
@@ -841,6 +861,7 @@ static int cb_find_init(char *path, DIR *parent, DIR *dir, void *data)
                         decision = find_time_check(st, param, 0);
         }
 
+print_path:
         if (decision != -1) {
                 printf("%s", path);
                 if (param->zeroend)
@@ -1131,12 +1152,17 @@ int llapi_catinfo(char *dir, char *keyword, char *node_name)
         return rc;
 }
 
+/* Is this a lustre fs? */
+int llapi_is_lustre_mnttype(const char *type)
+{
+        return (strcmp(type, "lustre") == 0 || strcmp(type,"lustre_lite") == 0);
+}
+
 /* Is this a lustre client fs? */
-int llapi_is_lustre_mnttype(struct mntent *mnt)
+int llapi_is_lustre_mnt(struct mntent *mnt)
 {
-        char *type = mnt->mnt_type;
-        return ((strcmp(type, "lustre") == 0 || strcmp(type,"lustre_lite") == 0)
-                && (strstr(mnt->mnt_fsname, ":/") != NULL));
+        return (llapi_is_lustre_mnttype(mnt->mnt_type) &&
+                strstr(mnt->mnt_fsname, ":/") != NULL);
 }
 
 int llapi_quotacheck(char *mnt, int check_type)
@@ -1240,10 +1266,14 @@ static int cb_quotachown(char *path, DIR *parent, DIR *d, void *data)
         /* libc chown() will do extra check, and if the real owner is
          * the same as the ones to set, it won't fall into kernel, so
          * invoke syscall directly. */
-        rc = syscall(SYS_chown, path, st->st_uid, st->st_gid);
+        rc = syscall(SYS_chown, path, -1, -1);
         if (rc)
-                err_msg("error: chown %s (%u,%u)",
-                        path, st->st_uid, st->st_gid);
+                err_msg("error: chown %s (%u,%u)", path);
+
+        rc = chmod(path, st->st_mode);
+        if (rc)
+                err_msg("error: chmod %s (%hu)", path, st->st_mode);
+
         return rc;
 }
 
@@ -1267,3 +1297,68 @@ out:
         find_param_fini(&param);
         return ret;
 }
+
+int llapi_getfacl(char *fname, char *cmd)
+{
+        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);
+                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);
+        } else {
+                printf("%s", out);
+        }
+
+        return rc;
+}
+
+int llapi_setfacl(char *fname, char *cmd)
+{
+        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);
+                return -1;
+        }
+
+        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);
+        } else {
+                printf("%s", out);
+        }
+
+        return rc;
+}