Whamcloud - gitweb
LU-8724 utils: Use open() instead of opendir() with dirfd()
[fs/lustre-release.git] / lustre / utils / liblustreapi.c
index e0ed3bb..44747e6 100644 (file)
  *
  * You should have received a copy of the GNU General Public License
  * version 2 along with this program; If not, see
- * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * http://www.gnu.org/licenses/gpl-2.0.html
  *
  * GPL HEADER END
  */
@@ -27,7 +23,7 @@
  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2015, Intel Corporation.
+ * Copyright (c) 2011, 2016, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
@@ -1743,23 +1739,23 @@ int llapi_lov_get_uuids(int fd, struct obd_uuid *uuidp, int *ost_count)
 
 int llapi_get_obd_count(char *mnt, int *count, int is_mdt)
 {
-        DIR *root;
-        int rc;
+       int root;
+       int rc;
 
-        root = opendir(mnt);
-        if (!root) {
-                rc = -errno;
-                llapi_error(LLAPI_MSG_ERROR, rc, "open %s failed", mnt);
-                return rc;
-        }
+       root = open(mnt, O_RDONLY | O_DIRECTORY);
+       if (root < 0) {
+               rc = -errno;
+               llapi_error(LLAPI_MSG_ERROR, rc, "open %s failed", mnt);
+               return rc;
+       }
 
-        *count = is_mdt;
-        rc = ioctl(dirfd(root), LL_IOC_GETOBDCOUNT, count);
-        if (rc < 0)
-                rc = -errno;
+       *count = is_mdt;
+       rc = ioctl(root, LL_IOC_GETOBDCOUNT, count);
+       if (rc < 0)
+               rc = -errno;
 
-        closedir(root);
-        return rc;
+       close(root);
+       return rc;
 }
 
 /* Check if user specified value matches a real uuid.  Ignore _UUID,
@@ -1787,7 +1783,7 @@ int llapi_uuid_match(char *real_uuid, char *search_uuid)
 
 /* Here, param->fp_obd_uuid points to a single obduuid, the index of which is
  * returned in param->fp_obd_index */
-static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param)
+static int setup_obd_uuid(int fd, char *dname, struct find_param *param)
 {
        struct obd_uuid obd_uuid;
        char buf[PATH_MAX];
@@ -1801,9 +1797,9 @@ static int setup_obd_uuid(DIR *dir, char *dname, struct find_param *param)
 
        /* Get the lov/lmv name */
        if (param->fp_get_lmv)
-               rc = llapi_file_fget_lmv_uuid(dirfd(dir), &obd_uuid);
+               rc = llapi_file_fget_lmv_uuid(fd, &obd_uuid);
        else
-               rc = llapi_file_fget_lov_uuid(dirfd(dir), &obd_uuid);
+               rc = llapi_file_fget_lov_uuid(fd, &obd_uuid);
        if (rc) {
                if (rc != -ENOTTY) {
                        llapi_error(LLAPI_MSG_ERROR, rc,
@@ -1990,17 +1986,17 @@ static int setup_target_indexes(DIR *dir, char *path, struct find_param *param)
 
 int llapi_ostlist(char *path, struct find_param *param)
 {
-        DIR *dir;
-        int ret;
+       int fd;
+       int ret;
 
-        dir = opendir(path);
-        if (dir == NULL)
-                return -errno;
+       fd = open(path, O_RDONLY | O_DIRECTORY);
+       if (fd < 0)
+               return -errno;
 
-        ret = setup_obd_uuid(dir, path, param);
-        closedir(dir);
+       ret = setup_obd_uuid(fd, path, param);
+       close(fd);
 
-        return ret;
+       return ret;
 }
 
 /*
@@ -2103,13 +2099,13 @@ static int sattr_cache_get_defaults(const char *const fsname,
 }
 
 static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
-                                     struct lov_user_ost_data_v1 *objects,
-                                     int is_dir, int verbose, int depth,
-                                     int raw, char *pool_name)
+                                    struct lov_user_ost_data_v1 *objects,
+                                    int is_dir, int verbose, int depth,
+                                    int raw, char *pool_name)
 {
-        char *prefix = is_dir ? "" : "lmm_";
+       char *prefix = is_dir ? "" : "lmm_";
        char *separator = "";
-        int rc;
+       int rc;
 
        if (is_dir && lmm_oi_seq(&lum->lmm_oi) == FID_SEQ_LOV_DEFAULT) {
                lmm_oi_set_seq(&lum->lmm_oi, 0);
@@ -2117,8 +2113,8 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
                        llapi_printf(LLAPI_MSG_NORMAL, "(Default) ");
        }
 
-        if (depth && path && ((verbose != VERBOSE_OBJID) || !is_dir))
-                llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path);
+       if (depth && path && ((verbose != VERBOSE_OBJID) || !is_dir))
+               llapi_printf(LLAPI_MSG_NORMAL, "%s\n", path);
 
        if ((verbose & VERBOSE_DETAIL) && !is_dir) {
                llapi_printf(LLAPI_MSG_NORMAL, "lmm_magic:          0x%08X\n",
@@ -2128,58 +2124,86 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
                llapi_printf(LLAPI_MSG_NORMAL, "lmm_object_id:      %#jx\n",
                             (uintmax_t)lmm_oi_id(&lum->lmm_oi));
        }
+       if ((verbose & (VERBOSE_DETAIL | VERBOSE_DFID)) && !is_dir) {
+               if (verbose & ~VERBOSE_DFID)
+                       llapi_printf(LLAPI_MSG_NORMAL, "lmm_fid:            ");
+               /* This needs a bit of hand-holding since old 1.x lmm_oi
+                * have { oi.oi_id = mds_inum, oi.oi_seq = 0 } and 2.x lmm_oi
+                * have { oi.oi_id = mds_oid, oi.oi_seq = mds_seq } instead of
+                * a real FID.  Ideally the 2.x code would have stored this
+                * like a FID with { oi_id = mds_seq, oi_seq = mds_oid } so the
+                * ostid union lu_fid { f_seq = mds_seq, f_oid = mds_oid }
+                * worked properly (especially since IGIF FIDs use mds_inum as
+                * the FID SEQ), but unfortunately that didn't happen.
+                *
+                * Print it to look like an IGIF FID, even though the fields
+                * are reversed on disk, so that it makes sense to userspace.
+                *
+                * Don't use ostid_id() and ostid_seq(), since they assume the
+                * oi_fid fields are in the right order.  This is why there are
+                * separate lmm_oi_seq() and lmm_oi_id() routines for this.
+                *
+                * For newer layout types hopefully this will be a real FID. */
+               llapi_printf(LLAPI_MSG_NORMAL, DFID"\n",
+                            lmm_oi_seq(&lum->lmm_oi) == 0 ?
+                               lmm_oi_id(&lum->lmm_oi) :
+                               lmm_oi_seq(&lum->lmm_oi),
+                            lmm_oi_seq(&lum->lmm_oi) == 0 ?
+                               0 : (__u32)lmm_oi_id(&lum->lmm_oi),
+                            (__u32)(lmm_oi_id(&lum->lmm_oi) >> 32));
+       }
 
-        if (verbose & VERBOSE_COUNT) {
-                if (verbose & ~VERBOSE_COUNT)
-                        llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_count:   ",
-                                     prefix);
-                if (is_dir) {
-                        if (!raw && lum->lmm_stripe_count == 0) {
-                                unsigned int scount;
-                                rc = sattr_cache_get_defaults(NULL, path,
-                                                              &scount, NULL,
-                                                              NULL);
-                                if (rc == 0)
+       if (verbose & VERBOSE_COUNT) {
+               if (verbose & ~VERBOSE_COUNT)
+                       llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_count:   ",
+                                    prefix);
+               if (is_dir) {
+                       if (!raw && lum->lmm_stripe_count == 0) {
+                               unsigned int scount;
+                               rc = sattr_cache_get_defaults(NULL, path,
+                                                             &scount, NULL,
+                                                             NULL);
+                               if (rc == 0)
                                        llapi_printf(LLAPI_MSG_NORMAL, "%d",
                                                     scount);
-                                else
-                                        llapi_error(LLAPI_MSG_ERROR, rc,
-                                                    "Cannot determine default"
-                                                    " stripe count.");
-                        } else {
+                               else
+                                       llapi_error(LLAPI_MSG_ERROR, rc,
+                                                   "Cannot determine default"
+                                                   " stripe count.");
+                       } else {
                                llapi_printf(LLAPI_MSG_NORMAL, "%d",
-                                             lum->lmm_stripe_count ==
-                                             (typeof(lum->lmm_stripe_count))(-1)
+                                            lum->lmm_stripe_count ==
+                                            (typeof(lum->lmm_stripe_count))(-1)
                                             ? -1 : lum->lmm_stripe_count);
-                        }
-                } else {
+                       }
+               } else {
                        llapi_printf(LLAPI_MSG_NORMAL, "%hd",
                                     (__s16)lum->lmm_stripe_count);
-                }
+               }
                separator = is_dir ? " " : "\n";
-        }
+       }
 
-        if (verbose & VERBOSE_SIZE) {
+       if (verbose & VERBOSE_SIZE) {
                llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
-                if (verbose & ~VERBOSE_SIZE)
-                        llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_size:    ",
-                                     prefix);
-                if (is_dir && !raw && lum->lmm_stripe_size == 0) {
-                        unsigned int ssize;
-                        rc = sattr_cache_get_defaults(NULL, path, NULL, &ssize,
-                                                      NULL);
-                        if (rc == 0)
+               if (verbose & ~VERBOSE_SIZE)
+                       llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_size:    ",
+                                    prefix);
+               if (is_dir && !raw && lum->lmm_stripe_size == 0) {
+                       unsigned int ssize;
+                       rc = sattr_cache_get_defaults(NULL, path, NULL, &ssize,
+                                                     NULL);
+                       if (rc == 0)
                                llapi_printf(LLAPI_MSG_NORMAL, "%u", ssize);
-                        else
-                                llapi_error(LLAPI_MSG_ERROR, rc,
-                                            "Cannot determine default"
-                                            " stripe size.");
-                } else {
+                       else
+                               llapi_error(LLAPI_MSG_ERROR, rc,
+                                           "Cannot determine default"
+                                           " stripe size.");
+               } else {
                        llapi_printf(LLAPI_MSG_NORMAL, "%u",
                                     lum->lmm_stripe_size);
-                }
+               }
                separator = is_dir ? " " : "\n";
-        }
+       }
 
        if ((verbose & VERBOSE_LAYOUT) && !is_dir) {
                llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
@@ -2190,42 +2214,42 @@ static void lov_dump_user_lmm_header(struct lov_user_md *lum, char *path,
                separator = "\n";
        }
 
-        if ((verbose & VERBOSE_GENERATION) && !is_dir) {
+       if ((verbose & VERBOSE_GENERATION) && !is_dir) {
                llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
-                if (verbose & ~VERBOSE_GENERATION)
-                        llapi_printf(LLAPI_MSG_NORMAL, "%slayout_gen:     ",
-                                     prefix);
+               if (verbose & ~VERBOSE_GENERATION)
+                       llapi_printf(LLAPI_MSG_NORMAL, "%slayout_gen:     ",
+                                    prefix);
                llapi_printf(LLAPI_MSG_NORMAL, "%u",
                             (int)lum->lmm_layout_gen);
                separator = "\n";
-        }
+       }
 
-        if (verbose & VERBOSE_OFFSET) {
+       if (verbose & VERBOSE_OFFSET) {
                llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
-                if (verbose & ~VERBOSE_OFFSET)
-                        llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_offset:  ",
-                                     prefix);
-                if (is_dir)
+               if (verbose & ~VERBOSE_OFFSET)
+                       llapi_printf(LLAPI_MSG_NORMAL, "%sstripe_offset:  ",
+                                    prefix);
+               if (is_dir)
                        llapi_printf(LLAPI_MSG_NORMAL, "%d",
-                                     lum->lmm_stripe_offset ==
-                                     (typeof(lum->lmm_stripe_offset))(-1) ? -1 :
+                                    lum->lmm_stripe_offset ==
+                                    (typeof(lum->lmm_stripe_offset))(-1) ? -1 :
                                     lum->lmm_stripe_offset);
-                else
+               else
                        llapi_printf(LLAPI_MSG_NORMAL, "%u",
                                     objects[0].l_ost_idx);
                separator = is_dir ? " " : "\n";
-        }
+       }
 
-        if ((verbose & VERBOSE_POOL) && (pool_name != NULL)) {
+       if ((verbose & VERBOSE_POOL) && (pool_name != NULL)) {
                llapi_printf(LLAPI_MSG_NORMAL, "%s", separator);
-                if (verbose & ~VERBOSE_POOL)
-                        llapi_printf(LLAPI_MSG_NORMAL, "%spool:           ",
-                                     prefix);
+               if (verbose & ~VERBOSE_POOL)
+                       llapi_printf(LLAPI_MSG_NORMAL, "%spool:           ",
+                                    prefix);
                llapi_printf(LLAPI_MSG_NORMAL, "%s", pool_name);
-        }
+       }
 
-        if (!is_dir || (is_dir && (verbose != VERBOSE_OBJID)))
-                llapi_printf(LLAPI_MSG_NORMAL, "\n");
+       if (!is_dir || (is_dir && (verbose != VERBOSE_OBJID)))
+               llapi_printf(LLAPI_MSG_NORMAL, "\n");
 }
 
 void lov_dump_user_lmm_v1v3(struct lov_user_md *lum, char *pool_name,
@@ -3219,10 +3243,10 @@ static int cb_getstripe(char *path, DIR *parent, DIR **dirp, void *data,
 
        if (param->fp_obd_uuid) {
                param->fp_quiet = 1;
-                ret = setup_obd_uuid(d ? d : parent, path, param);
-                if (ret)
-                        return ret;
-        }
+               ret = setup_obd_uuid(d ? dirfd(d) : dirfd(parent), path, param);
+               if (ret)
+                       return ret;
+       }
 
        if (d) {
                if (param->fp_get_lmv || param->fp_get_default_lmv) {
@@ -3332,11 +3356,9 @@ int llapi_getstripe(char *path, struct find_param *param)
                               cb_common_fini, param);
 }
 
-int llapi_obd_statfs(char *path, __u32 type, __u32 index,
-                     struct obd_statfs *stat_buf,
-                     struct obd_uuid *uuid_buf)
+int llapi_obd_fstatfs(int fd, __u32 type, __u32 index,
+                     struct obd_statfs *stat_buf, struct obd_uuid *uuid_buf)
 {
-        int fd;
         char raw[OBD_MAX_IOCTL_BUFFER] = {'\0'};
         char *rawbuf = raw;
         struct obd_ioctl_data data = { 0 };
@@ -3358,23 +3380,31 @@ int llapi_obd_statfs(char *path, __u32 type, __u32 index,
                 return rc;
         }
 
-        fd = open(path, O_RDONLY);
-        if (errno == EISDIR)
-                fd = open(path, O_DIRECTORY | O_RDONLY);
+       rc = ioctl(fd, IOC_OBD_STATFS, (void *)rawbuf);
+
+       return rc < 0 ? -errno : 0;
+}
 
+int llapi_obd_statfs(char *path, __u32 type, __u32 index,
+                    struct obd_statfs *stat_buf, struct obd_uuid *uuid_buf)
+{
+       int fd;
+       int rc;
+
+       fd = open(path, O_RDONLY);
        if (fd < 0) {
-               rc = errno ? -errno : -EBADF;
+               rc = -errno;
                llapi_error(LLAPI_MSG_ERROR, rc, "error: %s: opening '%s'",
                            __func__, path);
                /* If we can't even open a file on the filesystem (e.g. with
                 * -ESHUTDOWN), force caller to exit or it will loop forever. */
                return -ENODEV;
        }
-       rc = ioctl(fd, IOC_OBD_STATFS, (void *)rawbuf);
-       if (rc)
-               rc = errno ? -errno : -EINVAL;
+
+       rc = llapi_obd_fstatfs(fd, type, index, stat_buf, uuid_buf);
 
        close(fd);
+
        return rc;
 }
 
@@ -3501,22 +3531,30 @@ int llapi_is_lustre_mnt(struct mntent *mnt)
 
 int llapi_quotactl(char *mnt, struct if_quotactl *qctl)
 {
-        DIR *root;
-        int rc;
+       char fsname[PATH_MAX + 1];
+       int root;
+       int rc;
 
-        root = opendir(mnt);
-        if (!root) {
-                rc = -errno;
-                llapi_error(LLAPI_MSG_ERROR, rc, "open %s failed", mnt);
-                return rc;
-        }
+       rc = llapi_search_fsname(mnt, fsname);
+       if (rc) {
+               llapi_err_noerrno(LLAPI_MSG_ERROR,
+                                 "'%s' isn't on Lustre filesystem", mnt);
+               return rc;
+       }
 
-       rc = ioctl(dirfd(root), OBD_IOC_QUOTACTL, qctl);
-        if (rc < 0)
-                rc = -errno;
+       root = open(mnt, O_RDONLY | O_DIRECTORY);
+       if (root < 0) {
+               rc = -errno;
+               llapi_error(LLAPI_MSG_ERROR, rc, "open %s failed", mnt);
+               return rc;
+       }
 
-        closedir(root);
-        return rc;
+       rc = ioctl(root, OBD_IOC_QUOTACTL, qctl);
+       if (rc < 0)
+               rc = -errno;
+
+       close(root);
+       return rc;
 }
 
 /* Print mdtname 'name' into 'buf' using 'format'.  Add -MDT0000 if needed.
@@ -3804,6 +3842,7 @@ int llapi_changelog_clear(const char *mdtname, const char *idstr,
 int llapi_fid2path(const char *device, const char *fidstr, char *buf,
                   int buflen, long long *recno, int *linkno)
 {
+       const char *fidstr_orig = fidstr;
        struct lu_fid fid;
        struct getinfo_fid2path *gf;
        int rc;
@@ -3814,8 +3853,8 @@ int llapi_fid2path(const char *device, const char *fidstr, char *buf,
        sscanf(fidstr, SFID, RFID(&fid));
        if (!fid_is_sane(&fid)) {
                llapi_err_noerrno(LLAPI_MSG_ERROR,
-                                 "bad FID format [%s], should be [seq:oid:ver]"
-                                 " (e.g. "DFID")\n", fidstr,
+                                 "bad FID format '%s', should be [seq:oid:ver]"
+                                 " (e.g. "DFID")\n", fidstr_orig,
                                  (unsigned long long)FID_SEQ_NORMAL, 2, 0);
                return -EINVAL;
        }
@@ -3823,6 +3862,7 @@ int llapi_fid2path(const char *device, const char *fidstr, char *buf,
        gf = malloc(sizeof(*gf) + buflen);
        if (gf == NULL)
                return -ENOMEM;
+
        gf->gf_fid = fid;
        gf->gf_recno = *recno;
        gf->gf_linkno = *linkno;
@@ -3830,21 +3870,20 @@ int llapi_fid2path(const char *device, const char *fidstr, char *buf,
 
        /* Take path or fsname */
        rc = root_ioctl(device, OBD_IOC_FID2PATH, gf, NULL, 0);
-       if (rc) {
-               if (rc != -ENOENT)
-                       llapi_error(LLAPI_MSG_ERROR, rc, "ioctl err %d", rc);
-       } else {
-               memcpy(buf, gf->gf_u.gf_path, gf->gf_pathlen);
-               if (buf[0] == '\0') { /* ROOT path */
-                       buf[0] = '/';
-                       buf[1] = '\0';
-               }
-               *recno = gf->gf_recno;
-               *linkno = gf->gf_linkno;
-        }
+       if (rc)
+               goto out_free;
 
-        free(gf);
-        return rc;
+       memcpy(buf, gf->gf_u.gf_path, gf->gf_pathlen);
+       if (buf[0] == '\0') { /* ROOT path */
+               buf[0] = '/';
+               buf[1] = '\0';
+       }
+       *recno = gf->gf_recno;
+       *linkno = gf->gf_linkno;
+
+out_free:
+       free(gf);
+       return rc;
 }
 
 static int fid_from_lma(const char *path, const int fd, lustre_fid *fid)
@@ -3957,24 +3996,24 @@ int llapi_path2parent(const char *path, unsigned int linkno,
 
 int llapi_get_connect_flags(const char *mnt, __u64 *flags)
 {
-        DIR *root;
-        int rc;
+       int root;
+       int rc;
 
-        root = opendir(mnt);
-        if (!root) {
-                rc = -errno;
-                llapi_error(LLAPI_MSG_ERROR, rc, "open %s failed", mnt);
-                return rc;
-        }
+       root = open(mnt, O_RDONLY | O_DIRECTORY);
+       if (root < 0) {
+               rc = -errno;
+               llapi_error(LLAPI_MSG_ERROR, rc, "open %s failed", mnt);
+               return rc;
+       }
 
-        rc = ioctl(dirfd(root), LL_IOC_GET_CONNECT_FLAGS, flags);
-        if (rc < 0) {
-                rc = -errno;
-                llapi_error(LLAPI_MSG_ERROR, rc,
-                            "ioctl on %s for getting connect flags failed", mnt);
-        }
-        closedir(root);
-        return rc;
+       rc = ioctl(root, LL_IOC_GET_CONNECT_FLAGS, flags);
+       if (rc < 0) {
+               rc = -errno;
+               llapi_error(LLAPI_MSG_ERROR, rc,
+                       "ioctl on %s for getting connect flags failed", mnt);
+       }
+       close(root);
+       return rc;
 }
 
 /**