Whamcloud - gitweb
New tag 2.15.63
[fs/lustre-release.git] / lustre / tests / ll_dirstripe_verify.c
index be20a72..e6d4472 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
  */
  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, Intel Corporation.
+ * Copyright (c) 2011, 2017, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
- * Lustre is a trademark of Sun Microsystems, Inc.
  *
  * lustre/tests/ll_dirstripe_verify.c
  *
 #include <errno.h>
 #include <dirent.h>
 
-#include <liblustre.h>
-#include <obd.h>
-#include <lustre_lib.h>
+#include <libcfs/util/param.h>
+#include <libcfs/util/string.h>
 #include <lustre/lustreapi.h>
-#include <obd_lov.h>
-
-#include <lnet/lnetctl.h>
-
+#include <linux/lustre/lustre_idl.h>
 
 #define MAX_LOV_UUID_COUNT      1000
-union {
-        struct obd_uuid uuid;
-        char name[0];
-} lov;
-#define lov_uuid lov.uuid
-#define lov_name lov.name
-
-/* Returns bytes read on success and a negative value on failure.
+
+/*
+ * Returns bytes read on success and a negative value on failure.
  * If zero bytes are read it will be treated as failure as such
  * zero cannot be returned from this function.
  */
-int read_proc_entry(char *proc_path, char *buf, int len)
+static int read_proc_entry(char *proc_path, char *buf, int len)
 {
        int rc, fd;
 
@@ -103,225 +89,276 @@ int read_proc_entry(char *proc_path, char *buf, int len)
        return rc;
 }
 
-int compare(struct lov_user_md *lum_dir, struct lov_user_md *lum_file1,
-            struct lov_user_md *lum_file2)
+static int compare(struct obd_uuid *puuid, struct lov_user_md *lum_dir,
+           struct lov_user_md *lum_file1, struct lov_user_md *lum_file2)
 {
-        int stripe_count = 0, min_stripe_count = 0, def_stripe_count = 1;
-        int stripe_size = 0;
-        int stripe_offset = -1;
-        int ost_count;
-        char buf[128];
-        char lov_path[PATH_MAX];
-        char tmp_path[PATH_MAX];
-        int i;
-        FILE *fp;
-
-       fp = popen("\\ls -d  /proc/fs/lustre/lov/*clilov* | head -1", "r");
-       if (fp == NULL) {
-               llapi_error(LLAPI_MSG_ERROR, -errno,
-                           "open(lustre/lov/*clilov*) failed");
+       int stripe_count = 0, min_stripe_count = 0, def_stripe_count = 1;
+       int stripe_size = 0;
+       int stripe_offset = -1;
+       int ost_count;
+       char buf[128];
+       glob_t path;
+       int i;
+
+       if (cfs_get_param_paths(&path, "lov/%s/stripecount", puuid->uuid) != 0)
+               return 2;
+       if (read_proc_entry(path.gl_pathv[0], buf, sizeof(buf)) < 0) {
+               cfs_free_param_data(&path);
+               return 5;
+       }
+       cfs_free_param_data(&path);
+       def_stripe_count = (short)atoi(buf);
+
+       if (cfs_get_param_paths(&path, "lov/%s/numobd", puuid->uuid) != 0)
                return 2;
-        }
+       if (read_proc_entry(path.gl_pathv[0], buf, sizeof(buf)) < 0) {
+               cfs_free_param_data(&path);
+               return 6;
+       }
+       cfs_free_param_data(&path);
+       ost_count = atoi(buf);
+
+       if (!lum_dir) {
+               stripe_count = def_stripe_count;
+               min_stripe_count = -1;
+       } else {
+               stripe_count = (signed short)lum_dir->lmm_stripe_count;
+               printf("dir stripe %d, ", stripe_count);
+               min_stripe_count = 1;
+       }
+
+       printf("default stripe %d, ost count %d\n",
+              def_stripe_count, ost_count);
+
+       if (stripe_count == 0) {
+               min_stripe_count = -1;
+               stripe_count = 1;
+       }
+
+       stripe_count = (stripe_count > 0 && stripe_count <= ost_count) ?
+                                               stripe_count : ost_count;
+       min_stripe_count = min_stripe_count > 0 ? stripe_count :
+                                               ((stripe_count + 1) / 2);
+
+       if (lum_file1->lmm_stripe_count != stripe_count ||
+           lum_file1->lmm_stripe_count < min_stripe_count) {
+               llapi_err_noerrno(LLAPI_MSG_ERROR,
+                                 "file1 stripe count %d != dir %d\n",
+                                 lum_file1->lmm_stripe_count, stripe_count);
+               return 7;
+       }
+
+       if (lum_file1->lmm_stripe_count < stripe_count)
+               llapi_err_noerrno(LLAPI_MSG_WARN,
+                                 "warning: file1 used fewer stripes %d < dir %d (likely due to bug 4900)\n",
+                                 lum_file1->lmm_stripe_count, stripe_count);
+
+       if (lum_dir)
+               stripe_size = (int)lum_dir->lmm_stripe_size;
+       if (stripe_size == 0) {
+               if (cfs_get_param_paths(&path, "lov/%s/stripesize",
+                                       puuid->uuid) != 0)
+                       return 2;
+               if (read_proc_entry(path.gl_pathv[0], buf, sizeof(buf)) < 0) {
+                       cfs_free_param_data(&path);
+                       return 5;
+               }
+               cfs_free_param_data(&path);
+
+               stripe_size = atoi(buf);
+       }
 
-       if (fscanf(fp, "%s", lov_path) < 1) {
-               llapi_error(LLAPI_MSG_ERROR, -EINVAL,
-                           "read(lustre/lov/*clilov*) failed");
-               pclose(fp);
-               return 3;
+       if (lum_file1->lmm_stripe_size != stripe_size) {
+               llapi_err_noerrno(LLAPI_MSG_ERROR,
+                                 "file1 stripe size %d != dir %d\n",
+                                 lum_file1->lmm_stripe_size, stripe_size);
+               return 8;
+       }
+
+       if (lum_dir)
+               stripe_offset = (short int)lum_dir->lmm_stripe_offset;
+       if (stripe_offset != -1) {
+               for (i = 0; i < stripe_count; i++)
+                       if (lum_file1->lmm_objects[i].l_ost_idx !=
+                           (stripe_offset + i) % ost_count) {
+                               llapi_err_noerrno(LLAPI_MSG_WARN,
+                                                 "warning: file1 non-sequential stripe[%d] %d != %d\n",
+                                                 i, lum_file1->lmm_objects[i].l_ost_idx,
+                                                 (stripe_offset + i) %
+                                                 ost_count);
+                       }
+       } else if (lum_file2) {
+               int next, idx, stripe = stripe_count - 1;
+
+               next = (lum_file1->lmm_objects[stripe].l_ost_idx + 1) %
+                       ost_count;
+               idx = lum_file2->lmm_objects[0].l_ost_idx;
+               if (idx != next) {
+                       llapi_err_noerrno(LLAPI_MSG_WARN,
+                                         "warning: non-sequential file1 stripe[%d] %d != file2 stripe[0] %d\n",
+                                         stripe,
+                                         lum_file1->lmm_objects[stripe].l_ost_idx,
+                                         idx);
+               }
        }
 
-        pclose(fp);
-
-        snprintf(tmp_path, sizeof(tmp_path) - 1, "%s/stripecount",
-                 lov_path);
-        if (read_proc_entry(tmp_path, buf, sizeof(buf)) < 0)
-                return 5;
-        def_stripe_count = (short)atoi(buf);
-
-        snprintf(tmp_path, sizeof(tmp_path) - 1, "%s/numobd", lov_path);
-        if (read_proc_entry(tmp_path, buf, sizeof(buf)) < 0)
-                return 6;
-        ost_count = atoi(buf);
-
-        if (lum_dir == NULL) {
-                stripe_count = def_stripe_count;
-                min_stripe_count = -1;
-        } else {
-                stripe_count = (signed short)lum_dir->lmm_stripe_count;
-                printf("dir stripe %d, ", stripe_count);
-                min_stripe_count = 1;
-        }
-
-        printf("default stripe %d, ost count %d\n",
-               def_stripe_count, ost_count);
-
-        if (stripe_count == 0) {
-                min_stripe_count = -1;
-                stripe_count = 1;
-        }
-
-        stripe_count = (stripe_count > 0 && stripe_count <= ost_count) ?
-                                                stripe_count : ost_count;
-        min_stripe_count = min_stripe_count > 0 ? stripe_count :
-                                                ((stripe_count + 1) / 2);
-
-        if (lum_file1->lmm_stripe_count != stripe_count ||
-            lum_file1->lmm_stripe_count < min_stripe_count) {
-                llapi_err_noerrno(LLAPI_MSG_ERROR,
-                                  "file1 stripe count %d != dir %d\n",
-                                  lum_file1->lmm_stripe_count, stripe_count);
-                return 7;
-        }
-
-        if (lum_file1->lmm_stripe_count < stripe_count)
-                llapi_err_noerrno(LLAPI_MSG_WARN,
-                                  "warning: file1 used fewer stripes"
-                                  " %d < dir %d (likely due to bug 4900)\n",
-                                  lum_file1->lmm_stripe_count, stripe_count);
-
-        if (lum_dir != NULL)
-                stripe_size = (int)lum_dir->lmm_stripe_size;
-        if (stripe_size == 0) {
-                snprintf(tmp_path, sizeof(tmp_path) - 1, "%s/stripesize",
-                         lov_path);
-                if (read_proc_entry(tmp_path, buf, sizeof(buf)) < 0)
-                        return 5;
-
-                stripe_size = atoi(buf);
-        }
-
-        if (lum_file1->lmm_stripe_size != stripe_size) {
-                llapi_err_noerrno(LLAPI_MSG_ERROR,
-                                  "file1 stripe size %d != dir %d\n",
-                                  lum_file1->lmm_stripe_size, stripe_size);
-                return 8;
-        }
-
-        if (lum_dir != NULL)
-                stripe_offset = (short int)lum_dir->lmm_stripe_offset;
-        if (stripe_offset != -1) {
-                for (i = 0; i < stripe_count; i++)
-                        if (lum_file1->lmm_objects[i].l_ost_idx !=
-                            (stripe_offset + i) % ost_count) {
-                                llapi_err_noerrno(LLAPI_MSG_WARN,
-                                          "warning: file1 non-sequential "
-                                          "stripe[%d] %d != %d\n", i,
-                                          lum_file1->lmm_objects[i].l_ost_idx,
-                                          (stripe_offset + i) % ost_count);
-                        }
-        } else if (lum_file2 != NULL) {
-                int next, idx, stripe = stripe_count - 1;
-                next = (lum_file1->lmm_objects[stripe].l_ost_idx + 1) %
-                       ost_count;
-                idx = lum_file2->lmm_objects[0].l_ost_idx;
-                if (idx != next) {
-                        llapi_err_noerrno(LLAPI_MSG_WARN,
-                                  "warning: non-sequential "
-                                  "file1 stripe[%d] %d != file2 stripe[0] %d\n",
-                                  stripe, lum_file1->lmm_objects[stripe].l_ost_idx,
-                                  idx);
-                }
-        }
-
-        return 0;
+       return 0;
+}
+
+static int compare_lum(struct obd_uuid *puuid, struct lov_user_md *lum_dir,
+               struct lov_user_md *lum_file1, struct lov_user_md *lum_file2)
+{
+       struct lov_comp_md_v1 *comp_dir, *comp_file1;
+       struct lov_user_md *sub_dir, *sub_file1;
+       int i, rc = 0;
+
+       if (!lum_dir || lum_dir->lmm_magic != LOV_MAGIC_COMP_V1)
+               return compare(puuid, lum_dir, lum_file1, lum_file2);
+
+       comp_dir = (struct lov_comp_md_v1 *)lum_dir;
+       comp_file1 = (struct lov_comp_md_v1 *)lum_file1;
+
+       if (lum_file1->lmm_magic != lum_dir->lmm_magic) {
+               llapi_err_noerrno(LLAPI_MSG_ERROR, "file1 magic %#x != %#x\n",
+                                 lum_file1->lmm_magic, lum_dir->lmm_magic);
+               return 10;
+       }
+
+       if (comp_file1->lcm_entry_count != comp_dir->lcm_entry_count) {
+               llapi_err_noerrno(LLAPI_MSG_ERROR, "file1 comp cnt %d != %d\n",
+                                 comp_file1->lcm_entry_count,
+                                 comp_dir->lcm_entry_count);
+               return 11;
+       }
+
+       for (i = 0; i < comp_dir->lcm_entry_count; i++) {
+               sub_dir = (struct lov_user_md *)((char *)comp_dir +
+                               comp_dir->lcm_entries[i].lcme_offset);
+               sub_file1 = (struct lov_user_md *)((char *)comp_file1 +
+                               comp_file1->lcm_entries[i].lcme_offset);
+
+               rc = compare(puuid, sub_dir, sub_file1, NULL);
+               if (rc)
+                       break;
+       }
+
+       return rc;
 }
 
 int main(int argc, char **argv)
 {
-        DIR * dir;
-        struct lov_user_md *lum_dir, *lum_file1 = NULL, *lum_file2 = NULL;
-        int rc;
-        int lum_size;
-
-        if (argc < 3) {
-                llapi_err_noerrno(LLAPI_MSG_ERROR,
-                                "Usage: %s <dirname> <filename1> [filename2]\n",
-                                argv[0]);
-                return 1;
-        }
-
-        dir = opendir(argv[1]);
-        if (dir == NULL) {
-                rc = -errno;
-                llapi_error(LLAPI_MSG_ERROR, rc,
-                            "error: %s opendir failed\n", argv[1]);
-                return rc;
-        }
+       struct lov_user_md *lum_dir, *lum_file1 = NULL, *lum_file2 = NULL;
+       struct obd_uuid uuid;
+       int lum_size, rc;
+       DIR *dir;
+
+       if (argc < 3) {
+               llapi_err_noerrno(LLAPI_MSG_ERROR,
+                                 "Usage: %s <dirname> <filename1> [filename2]\n",
+                                 argv[0]);
+               return 1;
+       }
+
+       dir = opendir(argv[1]);
+       if (!dir) {
+               rc = -errno;
+               llapi_error(LLAPI_MSG_ERROR, rc,
+                           "error: %s opendir failed", argv[1]);
+               return rc;
+       }
 
        lum_size = lov_user_md_size(MAX_LOV_UUID_COUNT, LOV_USER_MAGIC);
        lum_dir = (struct lov_user_md *)malloc(lum_size);
-       if (lum_dir == NULL) {
+       if (!lum_dir) {
                rc = -ENOMEM;
                llapi_error(LLAPI_MSG_ERROR, rc,
-                           "error: can't allocate %d bytes "
-                           "for dir EA", lum_size);
+                           "error: can't allocate %d bytes for dir EA",
+                           lum_size);
                goto cleanup;
        }
 
-        rc = llapi_file_get_stripe(argv[1], lum_dir);
-        if (rc) {
-                if (rc == -ENODATA) {
-                        free(lum_dir);
-                        lum_dir = NULL;
-                } else {
-                        llapi_error(LLAPI_MSG_ERROR, rc,
-                                    "error: can't get EA for %s\n", argv[1]);
-                        goto cleanup;
-                }
-        }
-
-        /* XXX should be llapi_lov_getname() */
-        rc = llapi_file_get_lov_uuid(argv[1], &lov_uuid);
-        if (rc) {
-                llapi_error(LLAPI_MSG_ERROR, rc,
-                            "error: can't get lov name for %s\n",
-                            argv[1]);
-                return rc;
-        }
-
-        if ((lum_file1 = (struct lov_user_md *)malloc(lum_size)) == NULL) {
-                rc = -ENOMEM;
-                llapi_error(LLAPI_MSG_ERROR, rc,
-                            "error: can't allocate %d bytes for EA\n",
-                            lum_size);
-                goto cleanup;
-        }
-
-        rc = llapi_file_get_stripe(argv[2], lum_file1);
-        if (rc) {
-                llapi_error(LLAPI_MSG_ERROR, rc,
-                            "error: unable to get EA for %s\n", argv[2]);
-                goto cleanup;
-        }
-
-        if (argc == 4) {
-                lum_file2 = (struct lov_user_md *)malloc(lum_size);
-                if (lum_file2 == NULL) {
-                        rc = -ENOMEM;
-                        llapi_error(LLAPI_MSG_ERROR, rc,
-                                    "error: can't allocate %d "
-                                    "bytes for file2 EA\n", lum_size);
-                        goto cleanup;
-                }
-
-                rc = llapi_file_get_stripe(argv[3], lum_file2);
-                if (rc) {
-                        llapi_error(LLAPI_MSG_ERROR, rc,
-                                    "error: can't get EA for %s\n", argv[3]);
-                        goto cleanup;
-                }
-        }
-
-        rc = compare(lum_dir, lum_file1, lum_file2);
+       rc = llapi_file_get_stripe(argv[1], lum_dir);
+       if (rc == -ENODATA) {
+               char root[PATH_MAX], path[PATH_MAX + 2];
+
+               rc = llapi_search_mounts(argv[1], 0, root, NULL);
+               if (rc) {
+                       llapi_error(LLAPI_MSG_ERROR, rc,
+                                   "error: can't get root path for %s\n",
+                                   argv[1]);
+                       goto cleanup;
+               }
+
+               snprintf(path, sizeof(path), "%s/.", root);
+               rc = llapi_file_get_stripe(path, lum_dir);
+               if (rc == -ENODATA) {
+                       free(lum_dir);
+                       lum_dir = NULL;
+               } else if (rc) {
+                       llapi_error(LLAPI_MSG_ERROR, rc,
+                                   "error: cant't get root's LOVEA for %s\n",
+                                   path);
+                       goto cleanup;
+               }
+       } else if (rc) {
+               llapi_error(LLAPI_MSG_ERROR, rc,
+                           "error: can't get LOVEA for %s", argv[1]);
+               goto cleanup;
+       }
+
+       /* XXX should be llapi_lov_getname() */
+       rc = llapi_file_get_lov_uuid(argv[1], &uuid);
+       if (rc) {
+               llapi_error(LLAPI_MSG_ERROR, rc,
+                           "error: can't get lov name for %s",
+                           argv[1]);
+               return rc;
+       }
+
+       lum_file1 = malloc(lum_size);
+       if (!lum_file1) {
+               rc = -ENOMEM;
+               llapi_error(LLAPI_MSG_ERROR, rc,
+                           "error: can't allocate %d bytes for EA",
+                           lum_size);
+               goto cleanup;
+       }
+
+       rc = llapi_file_get_stripe(argv[2], lum_file1);
+       if (rc) {
+               llapi_error(LLAPI_MSG_ERROR, rc,
+                           "error: unable to get EA for %s", argv[2]);
+               goto cleanup;
+       }
+
+       if (argc == 4) {
+               lum_file2 = (struct lov_user_md *)malloc(lum_size);
+               if (!lum_file2) {
+                       rc = -ENOMEM;
+                       llapi_error(LLAPI_MSG_ERROR, rc,
+                                   "error: can't allocate %d bytes for file2 EA",
+                                   lum_size);
+                       goto cleanup;
+               }
+
+               rc = llapi_file_get_stripe(argv[3], lum_file2);
+               if (rc) {
+                       llapi_error(LLAPI_MSG_ERROR, rc,
+                                   "error: can't get EA for %s", argv[3]);
+                       goto cleanup;
+               }
+       }
+
+       rc = compare_lum(&uuid, lum_dir, lum_file1, lum_file2);
 
 cleanup:
-        closedir(dir);
-        if (lum_dir != NULL)
-                free(lum_dir);
-        if (lum_file1 != NULL)
-                free(lum_file1);
-        if (lum_file2 != NULL)
-                free(lum_file2);
-
-        return rc;
+       closedir(dir);
+       if (lum_dir)
+               free(lum_dir);
+       if (lum_file1)
+               free(lum_file1);
+       if (lum_file2)
+               free(lum_file2);
+
+       return rc;
 }