Whamcloud - gitweb
LU-4629 utils: fix rsources leak
[fs/lustre-release.git] / lustre / utils / lfs.c
index 3e2752f..ef03636 100644 (file)
@@ -120,6 +120,7 @@ static int lfs_hsm_release(int argc, char **argv);
 static int lfs_hsm_remove(int argc, char **argv);
 static int lfs_hsm_cancel(int argc, char **argv);
 static int lfs_swap_layouts(int argc, char **argv);
+static int lfs_mv(int argc, char **argv);
 
 #define SETSTRIPE_USAGE(_cmd, _tgt) \
        "usage: "_cmd" [--stripe-count|-c <stripe_count>]\n"\
@@ -156,16 +157,18 @@ command_t cmdlist[] = {
        {"setdirstripe", lfs_setdirstripe, 0,
         "To create a remote directory on a specified MDT.\n"
         "usage: setdirstripe <--count|-c stripe_count>\n"
-        "[--index|-i mdt_index] [--hash-type|-t hash_type] <dir>\n"
+        "[--index|-i mdt_index] [--hash-type|-t hash_type]\n"
+        "[--default_stripe|-D ] <dir>\n"
         "\tstripe_count: stripe count of the striped directory\n"
         "\tmdt_index:  MDT index of first stripe\n"
-        "\thash_type:  hash type of the striped directory\n"},
+        "\thash_type:  hash type of the striped directory\n"
+        "\tdefault_stripe: set default dirstripe of the directory\n"},
        {"getdirstripe", lfs_getdirstripe, 0,
         "To list the striping info for a given directory\n"
         "or recursively for all directories in a directory tree.\n"
         "usage: getdirstripe [--obd|-O <uuid>] [--quiet|-q] [--verbose|-v]\n"
         "               [--count|-c ] [--index|-i ] [--raw|-R]\n"
-        "               [--recursive | -r] <dir> ..."},
+        "               [--recursive | -r] [ --default_stripe | -D ] <dir> "},
        {"mkdir", lfs_setdirstripe, 0,
         "To create a remote directory on a specified MDT. And this can only\n"
         "be done on MDT0 by administrator.\n"
@@ -322,13 +325,17 @@ command_t cmdlist[] = {
         "usage: hsm_cancel [--filelist FILELIST] [--data DATA] <file> ..."},
        {"swap_layouts", lfs_swap_layouts, 0, "Swap layouts between 2 files.\n"
         "usage: swap_layouts <path1> <path2>"},
-       {"migrate", lfs_setstripe, 0, "migrate file from one layout to "
+       {"migrate", lfs_setstripe, 0, "migrate file from one OST layout to "
         "another (may be not safe with concurent writes).\n"
         SETSTRIPE_USAGE("migrate  ", "<filename>")},
-        {"help", Parser_help, 0, "help"},
-        {"exit", Parser_quit, 0, "quit"},
-        {"quit", Parser_quit, 0, "quit"},
-        { 0, 0, 0, NULL }
+       {"mv", lfs_mv, 0,
+        "To move directories between MDTs.\n"
+        "usage: mv <directory|filename> [--mdt-index|-M] <mdt_index> "
+        "[--verbose|-v]\n"},
+       {"help", Parser_help, 0, "help"},
+       {"exit", Parser_quit, 0, "quit"},
+       {"quit", Parser_quit, 0, "quit"},
+       { 0, 0, 0, NULL }
 };
 
 #define MIGRATION_BLOCKS 1
@@ -1239,6 +1246,7 @@ static int lfs_getstripe_internal(int argc, char **argv,
                {"stripe-count",        no_argument,            0, 'c'},
                {"stripe_count",        no_argument,            0, 'c'},
                {"directory",           no_argument,            0, 'd'},
+               {"default",             no_argument,            0, 'D'},
                {"generation",          no_argument,            0, 'g'},
 #if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 53, 0)
                /* This formerly implied "stripe-index", but was explicitly
@@ -1278,7 +1286,7 @@ static int lfs_getstripe_internal(int argc, char **argv,
 
        param->maxdepth = 1;
        optind = 0;
-       while ((c = getopt_long(argc, argv, "cdghiLMoO:pqrRsSv",
+       while ((c = getopt_long(argc, argv, "cdDghiLMoO:pqrRsSv",
                                long_opts, NULL)) != -1) {
                switch (c) {
                case 'O':
@@ -1296,6 +1304,9 @@ static int lfs_getstripe_internal(int argc, char **argv,
                case 'd':
                        param->maxdepth = 0;
                        break;
+               case 'D':
+                       param->get_default_lmv = 1;
+                       break;
                case 'r':
                        param->recursive = 1;
                        break;
@@ -1460,18 +1471,19 @@ static int lfs_setdirstripe(int argc, char **argv)
        char                    *stripe_offset_opt = NULL;
        char                    *stripe_count_opt = NULL;
        char                    *stripe_hash_opt = NULL;
-       int                     flags = 0;
+       int                     default_stripe = 0;
 
        struct option long_opts[] = {
                {"count",       required_argument, 0, 'c'},
                {"index",       required_argument, 0, 'i'},
                {"hash-type",   required_argument, 0, 't'},
+               {"default_stripe", required_argument, 0, 'D'},
                {0, 0, 0, 0}
        };
 
        optind = 0;
 
-       while ((c = getopt_long(argc, argv, "c:i:t:", long_opts, NULL)) >= 0) {
+       while ((c = getopt_long(argc, argv, "c:Di:t:", long_opts, NULL)) >= 0) {
                switch (c) {
                case 0:
                        /* Long options. */
@@ -1479,6 +1491,9 @@ static int lfs_setdirstripe(int argc, char **argv)
                case 'c':
                        stripe_count_opt = optarg;
                        break;
+               case 'D':
+                       default_stripe = 1;
+                       break;
                case 'i':
                        stripe_offset_opt = optarg;
                        break;
@@ -1538,8 +1553,16 @@ static int lfs_setdirstripe(int argc, char **argv)
 
        dname = argv[optind];
        do {
-               result = llapi_dir_create_pool(dname, flags, stripe_offset,
-                                              stripe_count, hash_type, NULL);
+               if (default_stripe == 1) {
+                       result = llapi_dir_set_default_lmv_stripe(dname,
+                                                   stripe_offset, stripe_count,
+                                                   hash_type, NULL);
+               } else {
+                       result = llapi_dir_create_pool(dname, 0, stripe_offset,
+                                                      stripe_count, hash_type,
+                                                      NULL);
+               }
+
                if (result) {
                        fprintf(stderr, "error: %s: create stripe dir '%s' "
                                "failed\n", argv[0], dname);
@@ -1578,6 +1601,58 @@ static int lfs_rmentry(int argc, char **argv)
        return result;
 }
 
+static int lfs_mv(int argc, char **argv)
+{
+       struct  find_param param = { .maxdepth = -1, .mdtindex = -1};
+       char   *end;
+       int     c;
+       int     rc = 0;
+       struct option long_opts[] = {
+               {"--mdt-index", required_argument, 0, 'M'},
+               {"verbose",     no_argument,       0, 'v'},
+               {0, 0, 0, 0}
+       };
+
+       while ((c = getopt_long(argc, argv, "M:v", long_opts, NULL)) != -1) {
+               switch (c) {
+               case 'M': {
+                       param.mdtindex = strtoul(optarg, &end, 0);
+                       if (*end != '\0') {
+                               fprintf(stderr, "%s: invalid MDT index'%s'\n",
+                                       argv[0], optarg);
+                               return CMD_HELP;
+                       }
+                       break;
+               }
+               case 'v': {
+                       param.verbose = VERBOSE_DETAIL;
+                       break;
+               }
+               default:
+                       fprintf(stderr, "error: %s: unrecognized option '%s'\n",
+                               argv[0], argv[optind - 1]);
+                       return CMD_HELP;
+               }
+       }
+
+       if (param.mdtindex == -1) {
+               fprintf(stderr, "%s MDT index must be indicated\n", argv[0]);
+               return CMD_HELP;
+       }
+
+       if (optind >= argc) {
+               fprintf(stderr, "%s missing operand path\n", argv[0]);
+               return CMD_HELP;
+       }
+
+       param.migrate = 1;
+       rc = llapi_mv(argv[optind], &param);
+       if (rc != 0)
+               fprintf(stderr, "cannot migrate '%s' to MDT%04x: %s\n",
+                       argv[optind], param.mdtindex, strerror(-rc));
+       return rc;
+}
+
 static int lfs_osts(int argc, char **argv)
 {
         return lfs_tgts(argc, argv);
@@ -1693,16 +1768,17 @@ struct ll_stat_type {
 static int mntdf(char *mntdir, char *fsname, char *pool, int ishow,
                int cooked, int lazy)
 {
-        struct obd_statfs stat_buf, sum = { .os_bsize = 1 };
-        struct obd_uuid uuid_buf;
-        char *poolname = NULL;
-        struct ll_stat_type types[] = { { LL_STATFS_LMV, "MDT" },
-                                        { LL_STATFS_LOV, "OST" },
-                                        { 0, NULL } };
-        struct ll_stat_type *tp;
-        __u32 index;
-        __u32 type;
-        int rc;
+       struct obd_statfs stat_buf, sum = { .os_bsize = 1 };
+       struct obd_uuid uuid_buf;
+       char *poolname = NULL;
+       struct ll_stat_type types[] = { { LL_STATFS_LMV, "MDT" },
+                                       { LL_STATFS_LOV, "OST" },
+                                       { 0, NULL } };
+       struct ll_stat_type *tp;
+       __u64 ost_ffree = 0;
+       __u32 index;
+       __u32 type;
+       int rc;
 
         if (pool) {
                 poolname = strchr(pool, '.');
@@ -1756,23 +1832,32 @@ static int mntdf(char *mntdir, char *fsname, char *pool, int ishow,
                                         sum.os_ffree += stat_buf.os_ffree;
                                         sum.os_files += stat_buf.os_files;
                                 } else /* if (tp->st_op == LL_STATFS_LOV) */ {
-                                        sum.os_blocks += stat_buf.os_blocks *
-                                                stat_buf.os_bsize;
-                                        sum.os_bfree  += stat_buf.os_bfree *
-                                                stat_buf.os_bsize;
-                                        sum.os_bavail += stat_buf.os_bavail *
-                                                stat_buf.os_bsize;
-                                }
-                        } else if (rc == -EINVAL || rc == -EFAULT) {
-                                break;
-                        }
-                }
-        }
+                                       sum.os_blocks += stat_buf.os_blocks *
+                                               stat_buf.os_bsize;
+                                       sum.os_bfree  += stat_buf.os_bfree *
+                                               stat_buf.os_bsize;
+                                       sum.os_bavail += stat_buf.os_bavail *
+                                               stat_buf.os_bsize;
+                                       ost_ffree += stat_buf.os_ffree;
+                               }
+                       } else if (rc == -EINVAL || rc == -EFAULT) {
+                               break;
+                       }
+               }
+       }
 
-        printf("\n");
-        showdf(mntdir, &sum, "filesystem summary:", ishow, cooked, NULL, 0,0);
-        printf("\n");
-        return 0;
+       /* If we don't have as many objects free on the OST as inodes
+        * on the MDS, we reduce the total number of inodes to
+        * compensate, so that the "inodes in use" number is correct.
+        * Matches ll_statfs_internal() so the results are consistent. */
+       if (ost_ffree < sum.os_ffree) {
+               sum.os_files = (sum.os_files - sum.os_ffree) + ost_ffree;
+               sum.os_ffree = ost_ffree;
+       }
+       printf("\n");
+       showdf(mntdir, &sum, "filesystem summary:", ishow, cooked, NULL, 0, 0);
+       printf("\n");
+       return 0;
 }
 
 static int lfs_df(int argc, char **argv)
@@ -3628,6 +3713,7 @@ static int lfs_hsm_request(int argc, char **argv, int action)
                                                strerror(errno));
                                        hur = oldhur;
                                        rc = -errno;
+                                       fclose(fp);
                                        goto out_free;
                                }
                                memcpy(hur, oldhur, hur_len(oldhur));
@@ -3644,8 +3730,10 @@ static int lfs_hsm_request(int argc, char **argv, int action)
                        rc = lfs_hsm_prepare_file(line, &hui->hui_fid,
                                                  &last_dev);
                        hur->hur_request.hr_itemcount++;
-                       if (rc)
+                       if (rc) {
+                               fclose(fp);
                                goto out_free;
+                       }
 
                        if ((some_file[0] == '\0') &&
                            (strlen(line) < sizeof(some_file)))