#include <time.h>
#include <ctype.h>
#include <zlib.h>
+#include <libgen.h>
#include "lfs_project.h"
#include <libcfs/util/string.h>
#include <linux/lustre/lustre_ver.h>
#include <linux/lustre/lustre_param.h>
#include <linux/lnet/nidstr.h>
+#include <cyaml.h>
#ifndef ARRAY_SIZE
# define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof((a)[0])))
" [--stripe-count|-c <stripe_count>]\n" \
" [--stripe-index|-i <start_ost_idx>]\n" \
" [--stripe-size|-S <stripe_size>]\n" \
- " [--layout|-L <pattern>]\n" \
+ " [--layout|-L <pattern>]\n" \
" [--pool|-p <pool_name>]\n" \
- " [--ost|-o <ost_indices>]\n"
+ " [--ost|-o <ost_indices>]\n" \
+ " [--yaml|-y <yaml_template_file>]\n" \
+ " [--copy=<lustre_src>]\n"
#define SSM_HELP_COMMON \
"\tstripe_count: Number of OSTs to stripe over (0=fs default, -1 all)\n" \
"\tcomp_end: Extent end of component, start after previous end.\n"\
"\t Can be specified with K, M or G (for KB, MB, GB\n" \
"\t respectively, -1 for EOF). Must be a multiple of\n"\
- "\t stripe_size.\n"
+ "\t stripe_size.\n" \
+ "\tyaml_template_file:\n" \
+ "\t YAML layout template file, can't be used with -c,\n" \
+ "\t -i, -S, -p, -o, or -E arguments.\n" \
+ "\tlustre_src: Lustre file/dir whose layout info is used to set\n" \
+ "\t another lustre file or directory, can't used with\n" \
+ "\t -c, -i, -S, -p, -o, or -E arguments.\n"
#define MIRROR_CREATE_HELP \
"\tmirror_count: Number of mirrors to be created with the upcoming\n" \
"\t It can be a plain layout or a composite layout.\n" \
"\t If not specified, the stripe options inherited\n" \
"\t from the previous component will be used.\n" \
- "\tparent: Use default stripe options from parent directory\n" \
"\tflags: set flags to the component of the current mirror.\n" \
"\t Only \"prefer\" flag is supported so far.\n"
#define MIRROR_EXTEND_USAGE \
" <--mirror-count|-N[mirror_count]>\n" \
- " [setstripe options|--parent|-f <victim_file>]\n" \
+ " [setstripe options|-f <victim_file>]\n" \
" [--no-verify]\n"
#define SETSTRIPE_USAGE \
.pc_help = "Create a mirrored file.\n"
"usage: lfs mirror create "
"<--mirror-count|-N[mirror_count]> "
- "[setstripe options|--parent] ... <filename|directory>\n"
+ "[setstripe options] ... <filename|directory>\n"
MIRROR_CREATE_HELP },
{ .pc_name = "extend", .pc_func = lfs_mirror_extend,
.pc_help = "Extend a mirrored file.\n"
"usage: lfs mirror extend "
"<--mirror-count|-N[mirror_count]> [--no-verify] "
- "[setstripe options|--parent|-f <victim_file>] ... <filename>\n"
+ "[setstripe options|-f <victim_file>] ... <filename>\n"
MIRROR_EXTEND_HELP },
{ .pc_name = "split", .pc_func = lfs_mirror_split,
.pc_help = "Split a mirrored file.\n"
"find files matching given attributes recursively in directory tree.\n"
"usage: find <directory|filename> ...\n"
" [[!] --atime|-A [+-]N] [[!] --ctime|-C [+-]N]\n"
- " [[!] --mtime|-M [+-]N] [--maxdepth|-D N]\n"
+ " [[!] --mtime|-M [+-]N] [--maxdepth|-D N] [[!] --blocks|-b N]\n"
" [[!] --mdt-index|--mdt|-m <uuid|index,...>]\n"
" [[!] --name|-n <pattern>] [[!] --ost|-O <uuid|index,...>]\n"
" [--print|-P] [--print0|-0] [[!] --size|-s [+-]N[bkMGTPE]]\n"
}
if (has_m_file && has_m_layout) {
- fprintf(stderr, "error: %s: -f <victim_file> option should not "
- "be specified with setstripe options or "
- "--parent option\n", progname);
+ fprintf(stderr,
+ "error: %s: -f <victim_file> option should not be specified with setstripe options\n",
+ progname);
return -EINVAL;
}
goto error;
}
- rc = lfs_component_create(fname, O_CREAT | O_WRONLY, 0644,
+ rc = lfs_component_create(fname, O_CREAT | O_WRONLY, 0666,
layout);
if (rc >= 0) {
close(rc);
fprintf(stderr, "error %s: file name of '%s' too long\n",
progname, fname);
rc = -ERANGE;
- goto free_layout;
+ goto close_fd;
}
strncpy(parent, fname, sizeof(parent));
ptr = strrchr(parent, '/');
fprintf(stderr, "error %s: getcwd failed: %s\n",
progname, strerror(errno));
rc = -errno;
- goto free_layout;
+ goto close_fd;
}
} else {
if (ptr == parent)
if (rc < 0) {
fprintf(stderr, "%s: cannot get MDT index of '%s'\n",
progname, fname);
- goto free_layout;
+ goto close_fd;
}
if (victim_file == NULL) {
__u32 lsa_comp_flags;
__u32 lsa_comp_neg_flags;
unsigned long long lsa_pattern;
+ unsigned int lsa_mirror_count;
int lsa_nr_tgts;
+ bool lsa_first_comp;
__u32 *lsa_tgts;
char *lsa_pool_name;
};
static inline void setstripe_args_init(struct lfs_setstripe_args *lsa)
{
+ unsigned int mirror_count = lsa->lsa_mirror_count;
+ bool first_comp = lsa->lsa_first_comp;
+
memset(lsa, 0, sizeof(*lsa));
lsa->lsa_stripe_size = LLAPI_LAYOUT_DEFAULT;
lsa->lsa_stripe_off = LLAPI_LAYOUT_DEFAULT;
lsa->lsa_pattern = LLAPI_LAYOUT_RAID0;
lsa->lsa_pool_name = NULL;
+
+ lsa->lsa_mirror_count = mirror_count;
+ lsa->lsa_first_comp = first_comp;
}
/**
* Return: 0 on success or an error code on failure.
*/
static int comp_args_to_layout(struct llapi_layout **composite,
- struct lfs_setstripe_args *lsa)
+ struct lfs_setstripe_args *lsa,
+ bool set_extent)
{
struct llapi_layout *layout = *composite;
uint64_t prev_end = 0;
return rc;
}
- rc = llapi_layout_comp_add(layout);
+ if (lsa->lsa_first_comp)
+ prev_end = 0;
+
+ if (lsa->lsa_first_comp)
+ rc = llapi_layout_add_first_comp(layout);
+ else
+ rc = llapi_layout_comp_add(layout);
if (rc) {
fprintf(stderr, "Add component failed. %s\n",
strerror(errno));
return rc;
}
}
+ /* reset lsa_first_comp */
+ lsa->lsa_first_comp = false;
- rc = llapi_layout_comp_extent_set(layout, prev_end, lsa->lsa_comp_end);
- if (rc) {
- fprintf(stderr, "Set extent [%lu, %llu) failed. %s\n",
- prev_end, lsa->lsa_comp_end, strerror(errno));
- return rc;
+ if (set_extent) {
+ rc = llapi_layout_comp_extent_set(layout, prev_end,
+ lsa->lsa_comp_end);
+ if (rc) {
+ fprintf(stderr, "Set extent [%lu, %llu) failed. %s\n",
+ prev_end, lsa->lsa_comp_end, strerror(errno));
+ return rc;
+ }
}
/* Data-on-MDT component setting */
lsa->lsa_stripe_count != LLAPI_LAYOUT_DEFAULT &&
lsa->lsa_stripe_count != LLAPI_LAYOUT_WIDE &&
lsa->lsa_nr_tgts != lsa->lsa_stripe_count) {
- fprintf(stderr, "stripe_count(%lld) != nr_osts(%d)\n",
+ fprintf(stderr, "stripe_count(%lld) != nr_tgts(%d)\n",
lsa->lsa_stripe_count, lsa->lsa_nr_tgts);
return -EINVAL;
}
if (rc)
break;
}
- } else if (lsa->lsa_stripe_off != LLAPI_LAYOUT_DEFAULT) {
+ } else if (lsa->lsa_stripe_off != LLAPI_LAYOUT_DEFAULT &&
+ lsa->lsa_stripe_off != -1) {
rc = llapi_layout_ost_index_set(layout, 0, lsa->lsa_stripe_off);
}
if (rc) {
return 0;
}
+static int build_component(struct llapi_layout **layout,
+ struct lfs_setstripe_args *lsa, bool set_extent)
+{
+ int rc;
+
+ rc = comp_args_to_layout(layout, lsa, set_extent);
+ if (rc)
+ return rc;
+
+ if (lsa->lsa_mirror_count > 0) {
+ rc = llapi_layout_mirror_count_set(*layout,
+ lsa->lsa_mirror_count);
+ if (rc)
+ return rc;
+
+ rc = llapi_layout_flags_set(*layout, LCM_FL_RDONLY);
+ if (rc)
+ return rc;
+ lsa->lsa_mirror_count = 0;
+ }
+
+ return rc;
+}
+
+static int build_layout_from_yaml_node(struct cYAML *node,
+ struct llapi_layout **layout,
+ struct lfs_setstripe_args *lsa,
+ __u32 *osts)
+{
+ char *string;
+ int rc = 0;
+
+ while (node) {
+ string = node->cy_string;
+ /* skip leading lmm_ if present, to simplify parsing */
+ if (string != NULL && strncmp(string, "lmm_", 4) == 0)
+ string += 4;
+
+ if (node->cy_type == CYAML_TYPE_STRING) {
+ if (!strcmp(string, "lcme_extent.e_end")) {
+ if (!strcmp(node->cy_valuestring, "EOF") ||
+ !strcmp(node->cy_valuestring, "eof"))
+ lsa->lsa_comp_end = LUSTRE_EOF;
+ } else if (!strcmp(string, "pool")) {
+ lsa->lsa_pool_name = node->cy_valuestring;
+ } else if (!strcmp(string, "pattern")) {
+ if (!strcmp(node->cy_valuestring, "mdt"))
+ lsa->lsa_pattern = LLAPI_LAYOUT_MDT;
+ }
+ } else if (node->cy_type == CYAML_TYPE_NUMBER) {
+ if (!strcmp(string, "lcm_mirror_count")) {
+ lsa->lsa_mirror_count = node->cy_valueint;
+ } else if (!strcmp(string, "lcme_extent.e_start")) {
+ if (node->cy_valueint != 0 || *layout != NULL) {
+ rc = build_component(layout, lsa, true);
+ if (rc)
+ return rc;
+ }
+
+ if (node->cy_valueint == 0)
+ lsa->lsa_first_comp = true;
+
+ /* initialize lsa */
+ setstripe_args_init(lsa);
+ lsa->lsa_tgts = osts;
+ } else if (!strcmp(string, "lcme_extent.e_end")) {
+ if (node->cy_valueint == -1)
+ lsa->lsa_comp_end = LUSTRE_EOF;
+ else
+ lsa->lsa_comp_end = node->cy_valueint;
+ } else if (!strcmp(string, "stripe_count")) {
+ lsa->lsa_stripe_count = node->cy_valueint;
+ } else if (!strcmp(string, "stripe_size")) {
+ lsa->lsa_stripe_size = node->cy_valueint;
+ } else if (!strcmp(string, "stripe_offset")) {
+ lsa->lsa_stripe_off = node->cy_valueint;
+ } else if (!strcmp(string, "l_ost_idx")) {
+ osts[lsa->lsa_nr_tgts] = node->cy_valueint;
+ lsa->lsa_nr_tgts++;
+ }
+ } else if (node->cy_type == CYAML_TYPE_OBJECT) {
+ /* go deep to sub blocks */
+ rc = build_layout_from_yaml_node(node->cy_child, layout,
+ lsa, osts);
+ if (rc)
+ return rc;
+ }
+ node = node->cy_next;
+ }
+
+ return rc;
+}
+
+static int lfs_comp_create_from_yaml(char *template,
+ struct llapi_layout **layout,
+ struct lfs_setstripe_args *lsa,
+ __u32 *osts)
+{
+ struct cYAML *tree = NULL, *err_rc = NULL;
+ int rc = 0;
+
+ tree = cYAML_build_tree(template, NULL, 0, &err_rc, false);
+ if (!tree) {
+ fprintf(stderr, "%s: cannot parse YAML file %s\n",
+ progname, template);
+ cYAML_build_error(-EINVAL, -1, "yaml", "from comp yaml",
+ "can't parse", &err_rc);
+ cYAML_print_tree2file(stderr, err_rc);
+ cYAML_free_tree(err_rc);
+ rc = -EINVAL;
+ goto err;
+ }
+
+ /* initialize lsa for plain file */
+ setstripe_args_init(lsa);
+ lsa->lsa_tgts = osts;
+
+ rc = build_layout_from_yaml_node(tree, layout, lsa, osts);
+ if (rc) {
+ fprintf(stderr, "%s: cannot build layout from YAML file %s.\n",
+ progname, template);
+ goto err;
+ } else {
+ rc = build_component(layout, lsa, *layout != NULL);
+ }
+ /* clean clean lsa */
+ setstripe_args_init(lsa);
+
+err:
+ if (tree)
+ cYAML_free_tree(tree);
+ return rc;
+}
+
/* In 'lfs setstripe --component-add' mode, we need to fetch the extent
* end of the last component in the existing file, and adjust the
* first extent start of the components to be added accordingly. */
LFS_COMP_DEL_OPT,
LFS_COMP_SET_OPT,
LFS_COMP_ADD_OPT,
- LFS_COMP_USE_PARENT_OPT,
LFS_COMP_NO_VERIFY_OPT,
LFS_PROJID_OPT,
LFS_MIRROR_FLAGS_OPT,
LFS_MIRROR_ID_OPT,
LFS_MIRROR_STATE_OPT,
+ LFS_LAYOUT_COPY,
};
/* functions */
static int lfs_setstripe_internal(int argc, char **argv,
enum setstripe_origin opc)
{
- struct lfs_setstripe_args lsa;
+ struct lfs_setstripe_args lsa = { 0 };
struct llapi_stripe_param *param = NULL;
struct find_param migrate_mdt_param = {
.fp_max_depth = -1,
.fp_mdt_index = -1,
};
char *fname;
- int result;
+ int result = 0;
int result2 = 0;
char *end;
int c;
struct mirror_args *last_mirror = NULL;
__u16 mirror_id = 0;
char cmd[PATH_MAX];
+ bool from_yaml = false;
+ bool from_copy = false;
+ char *template = NULL;
struct option long_opts[] = {
/* find { .val = 'A', .name = "atime", .has_arg = required_argument }*/
{ .val = LFS_COMP_SET_OPT,
.name = "component-set",
.has_arg = no_argument},
- { .val = LFS_COMP_USE_PARENT_OPT,
- .name = "parent", .has_arg = no_argument},
{ .val = LFS_COMP_NO_VERIFY_OPT,
.name = "no-verify", .has_arg = no_argument},
{ .val = LFS_MIRROR_FLAGS_OPT,
.name = "flags", .has_arg = required_argument},
{ .val = LFS_MIRROR_ID_OPT,
.name = "mirror-id", .has_arg = required_argument},
+ { .val = LFS_LAYOUT_COPY,
+ .name = "copy", .has_arg = required_argument},
{ .val = 'c', .name = "stripe-count", .has_arg = required_argument},
{ .val = 'c', .name = "stripe_count", .has_arg = required_argument},
/* find { .val = 'C', .name = "ctime", .has_arg = required_argument }*/
/* find { .val = 'U', .name = "user", .has_arg = required_argument }*/
/* --verbose is only valid in migrate mode */
{ .val = 'v', .name = "verbose", .has_arg = no_argument},
-/* getstripe { .val = 'y', .name = "yaml", .has_arg = no_argument }, */
+ { .val = 'y', .name = "yaml", .has_arg = required_argument },
{ .name = NULL } };
setstripe_args_init(&lsa);
snprintf(cmd, sizeof(cmd), "%s %s", progname, argv[0]);
progname = cmd;
- while ((c = getopt_long(argc, argv, "bc:dDE:f:i:I:m:N::no:p:L:s:S:v",
+ while ((c = getopt_long(argc, argv, "bc:dDE:f:i:I:m:N::no:p:L:s:S:vy:",
long_opts, NULL)) >= 0) {
switch (c) {
case 0:
case LFS_COMP_SET_OPT:
comp_set = 1;
break;
- case LFS_COMP_USE_PARENT_OPT:
- if (!mirror_mode) {
- fprintf(stderr, "error: %s: --parent must be "
- "specified with --mirror-count|-N "
- "option\n", progname);
- goto usage_error;
- }
- setstripe_args_init(&lsa);
- break;
case LFS_COMP_NO_VERIFY_OPT:
mirror_flags |= MF_NO_VERIFY;
break;
}
break;
}
+ case LFS_LAYOUT_COPY:
+ from_copy = true;
+ template = optarg;
+ break;
case 'b':
if (!migrate_mode) {
fprintf(stderr,
break;
case 'E':
if (lsa.lsa_comp_end != 0) {
- result = comp_args_to_layout(lpp, &lsa);
+ result = comp_args_to_layout(lpp, &lsa, true);
if (result) {
fprintf(stderr,
"%s %s: invalid layout\n",
if (lsa.lsa_comp_end == 0)
lsa.lsa_comp_end = LUSTRE_EOF;
- result = comp_args_to_layout(lpp, &lsa);
+ result = comp_args_to_layout(lpp, &lsa, true);
if (result) {
lfs_mirror_free(new_mirror);
goto error;
if (optarg == NULL)
goto usage_error;
lsa.lsa_pool_name = optarg;
+
+ if (strlen(lsa.lsa_pool_name) == 0 ||
+ strncmp(lsa.lsa_pool_name, "none",
+ LOV_MAXPOOLNAME) == 0)
+ lsa.lsa_pool_name = NULL;
break;
case 'S':
result = llapi_parse_size(optarg, &lsa.lsa_stripe_size,
}
migrate_mdt_param.fp_verbose = VERBOSE_DETAIL;
break;
+ case 'y':
+ from_yaml = true;
+ template = optarg;
+ break;
default:
fprintf(stderr, "%s %s: unrecognized option '%s'\n",
progname, argv[0], argv[optind - 1]);
}
if (lsa.lsa_comp_end != 0) {
- result = comp_args_to_layout(lpp, &lsa);
+ result = comp_args_to_layout(lpp, &lsa, true);
if (result)
goto error;
}
goto error;
}
+ if (from_yaml && from_copy) {
+ fprintf(stderr,
+ "%s: can't specify --yaml and --copy together\n",
+ progname);
+ goto error;
+ }
+
+ if ((from_yaml || from_copy) &&
+ (setstripe_args_specified(&lsa) || layout != NULL)) {
+ fprintf(stderr, "error: %s: can't specify --yaml with "
+ "-c, -S, -i, -o, -p or -E options.\n",
+ argv[0]);
+ goto error;
+ }
+
if (mdt_idx_arg != NULL && optind > 3) {
fprintf(stderr,
"%s %s: option -m cannot be used with other options\n",
}
}
+ if (from_yaml) {
+ /* generate a layout from a YAML template */
+ result = lfs_comp_create_from_yaml(template, &layout,
+ &lsa, osts);
+ if (result) {
+ fprintf(stderr, "error: %s: can't create composite "
+ "layout from template file %s\n",
+ argv[0], template);
+ goto error;
+ }
+ } else if (from_copy) {
+ layout = llapi_layout_get_by_path(template, 0);
+ if (layout == NULL) {
+ fprintf(stderr,
+ "%s: can't create composite layout from file %s.\n",
+ progname, template);
+ goto error;
+ }
+ }
+
for (fname = argv[optind]; fname != NULL; fname = argv[++optind]) {
if (mdt_idx_arg != NULL) {
result = llapi_migrate_mdt(fname, &migrate_mdt_param);
NULL);
} else if (layout != NULL) {
result = lfs_component_create(fname, O_CREAT | O_WRONLY,
- 0644, layout);
+ 0666, layout);
if (result >= 0) {
close(result);
result = 0;
} else {
result = llapi_file_open_param(fname,
O_CREAT | O_WRONLY,
- 0644, param);
+ 0666, param);
if (result >= 0) {
close(result);
result = 0;
};
struct option long_opts[] = {
{ .val = 'A', .name = "atime", .has_arg = required_argument },
+ { .val = 'b', .name = "blocks", .has_arg = required_argument },
{ .val = LFS_COMP_COUNT_OPT,
.name = "comp-count", .has_arg = required_argument },
{ .val = LFS_COMP_COUNT_OPT,
/* when getopt_long_only() hits '!' it returns 1, puts "!" in optarg */
while ((c = getopt_long_only(argc, argv,
- "-0A:c:C:D:E:g:G:H:i:L:m:M:n:N:O:Ppqrs:S:t:T:u:U:v",
+ "-0A:b:c:C:D:E:g:G:H:i:L:m:M:n:N:O:Ppqrs:S:t:T:u:U:v",
long_opts, NULL)) >= 0) {
xtime = NULL;
xsign = NULL;
if (rc)
*xsign = rc;
break;
+ case 'b':
+ if (optarg[0] == '+') {
+ param.fp_blocks_sign = -1;
+ optarg++;
+ } else if (optarg[0] == '-') {
+ param.fp_blocks_sign = 1;
+ optarg++;
+ }
+
+ param.fp_blocks_units = 1024;
+ ret = llapi_parse_size(optarg, ¶m.fp_blocks,
+ ¶m.fp_blocks_units, 0);
+ if (ret) {
+ fprintf(stderr, "error: bad blocks '%s'\n",
+ optarg);
+ goto err;
+ }
+ param.fp_check_blocks = 1;
+ param.fp_exclude_blocks = !!neg_opt;
+ break;
case LFS_COMP_COUNT_OPT:
if (optarg[0] == '+') {
param.fp_comp_count_sign = -1;
{
struct option long_opts[] = {
/* find { .val = 'A', .name = "atime", .has_arg = required_argument }*/
+/* find { .val = 'b', .name = "blocks", .has_arg = required_argument }*/
{ .val = LFS_COMP_COUNT_OPT,
.name = "comp-count", .has_arg = no_argument },
{ .val = LFS_COMP_COUNT_OPT,
return rc;
}
-/* functions */
-static int lfs_setdirstripe(int argc, char **argv)
+enum mntdf_flags {
+ MNTDF_INODES = 0x0001,
+ MNTDF_COOKED = 0x0002,
+ MNTDF_LAZY = 0x0004,
+ MNTDF_VERBOSE = 0x0008,
+ MNTDF_SHOW = 0x0010,
+};
+
+#define COOK(value) \
+({ \
+ int radix = 0; \
+ while (value > 1024) { \
+ value /= 1024; \
+ radix++; \
+ } \
+ radix; \
+})
+#define UUF "%-20s"
+#define CSF "%11s"
+#define CDF "%11llu"
+#define HDF "%8.1f%c"
+#define RSF "%4s"
+#define RDF "%3d%%"
+
+static inline int obd_statfs_ratio(const struct obd_statfs *st)
{
- char *dname;
- int result;
- struct lfs_setstripe_args lsa;
- struct llapi_stripe_param *param = NULL;
- __u32 mdts[LMV_MAX_STRIPE_COUNT] = { 0 };
- char *end;
- int c;
- char *mode_opt = NULL;
- bool default_stripe = false;
- mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
- mode_t previous_mode = 0;
- bool delete = false;
+ double avail, used, ratio = 0;
- struct option long_opts[] = {
- { .val = 'c', .name = "count", .has_arg = required_argument },
- { .val = 'c', .name = "mdt-count", .has_arg = required_argument },
- { .val = 'd', .name = "delete", .has_arg = no_argument },
- { .val = 'D', .name = "default", .has_arg = no_argument },
- { .val = 'D', .name = "default_stripe", .has_arg = no_argument },
- { .val = 'H', .name = "mdt-hash", .has_arg = required_argument },
- { .val = 'i', .name = "mdt-index", .has_arg = required_argument },
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
- { .val = 'i', .name = "index", .has_arg = required_argument },
-#endif
- { .val = 'o', .name = "mode", .has_arg = required_argument },
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
- { .val = 't', .name = "hash-type", .has_arg = required_argument },
-#endif
- { .val = 'T', .name = "mdt-count", .has_arg = required_argument },
- { .name = NULL } };
+ avail = st->os_bavail;
+ used = st->os_blocks - st->os_bfree;
+ if (avail + used > 0)
+ ratio = used / (used + avail) * 100 + 0.5;
- setstripe_args_init(&lsa);
+ return (int)ratio;
+}
- while ((c = getopt_long(argc, argv, "c:dDi:H:m:o:t:T:", long_opts,
- NULL)) >= 0) {
- switch (c) {
- case 0:
- /* Long options. */
- break;
- case 'c':
- case 'T':
- lsa.lsa_stripe_count = strtoul(optarg, &end, 0);
- if (*end != '\0') {
- fprintf(stderr,
- "%s %s: invalid stripe count '%s'\n",
- progname, argv[0], optarg);
- return CMD_HELP;
- }
- break;
- case 'd':
- delete = true;
- default_stripe = true;
- break;
- case 'D':
- default_stripe = true;
- break;
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
- case 't':
- fprintf(stderr, "warning: '--hash-type' and '-t' "
- "deprecated, use '--mdt-hash' or '-H' instead\n");
-#endif
- case 'H':
- lsa.lsa_pattern = check_hashtype(optarg);
- if (lsa.lsa_pattern == 0) {
- fprintf(stderr,
- "%s %s: bad stripe hash type '%s'\n",
- progname, argv[0], optarg);
- return CMD_HELP;
- }
- break;
- case 'i':
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
- if (strcmp(argv[optind - 1], "--index") == 0)
- fprintf(stderr,
- "%s %s: warning: '--index' deprecated, use '--mdt-index' instead\n",
- progname, argv[0]);
-#endif
- lsa.lsa_nr_tgts = parse_targets(mdts,
- sizeof(mdts) / sizeof(__u32),
- lsa.lsa_nr_tgts, optarg);
- if (lsa.lsa_nr_tgts < 0) {
- fprintf(stderr,
- "%s %s: invalid MDT target(s) '%s'\n",
- progname, argv[0], optarg);
- return CMD_HELP;
- }
+static int showdf(char *mntdir, struct obd_statfs *stat,
+ char *uuid, enum mntdf_flags flags,
+ char *type, int index, int rc)
+{
+ long long avail, used, total;
+ int ratio = 0;
+ char *suffix = "KMGTPEZY";
+ /* Note if we have >2^64 bytes/fs these buffers will need to be grown */
+ char tbuf[3 * sizeof(__u64)];
+ char ubuf[3 * sizeof(__u64)];
+ char abuf[3 * sizeof(__u64)];
+ char rbuf[3 * sizeof(__u64)];
- lsa.lsa_tgts = mdts;
- if (lsa.lsa_stripe_off == LLAPI_LAYOUT_DEFAULT)
- lsa.lsa_stripe_off = mdts[0];
- break;
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 16, 53, 0)
- case 'm':
- fprintf(stderr, "warning: '-m' is deprecated, "
- "use '--mode' or '-o' instead\n");
-#endif
- case 'o':
- mode_opt = optarg;
- break;
- default:
- fprintf(stderr, "%s %s: unrecognized option '%s'\n",
- progname, argv[0], argv[optind - 1]);
- return CMD_HELP;
+ if (!uuid || !stat)
+ return -EINVAL;
+
+ switch (rc) {
+ case 0:
+ if (flags & MNTDF_INODES) {
+ avail = stat->os_ffree;
+ used = stat->os_files - stat->os_ffree;
+ total = stat->os_files;
+ } else {
+ int shift = flags & MNTDF_COOKED ? 0 : 10;
+
+ avail = (stat->os_bavail * stat->os_bsize) >> shift;
+ used = ((stat->os_blocks - stat->os_bfree) *
+ stat->os_bsize) >> shift;
+ total = (stat->os_blocks * stat->os_bsize) >> shift;
}
- }
- if (optind == argc) {
- fprintf(stderr, "%s %s: DIR must be specified\n",
- progname, argv[0]);
- return CMD_HELP;
- }
+ ratio = obd_statfs_ratio(stat);
- if (!delete && lsa.lsa_stripe_off == LLAPI_LAYOUT_DEFAULT &&
- lsa.lsa_stripe_count == LLAPI_LAYOUT_DEFAULT) {
- fprintf(stderr,
- "%s %s: stripe offset and count must be specified\n",
- progname, argv[0]);
- return CMD_HELP;
+ if (flags & MNTDF_COOKED) {
+ int i;
+ double cook_val;
+
+ cook_val = (double)total;
+ i = COOK(cook_val);
+ if (i > 0)
+ snprintf(tbuf, sizeof(tbuf), HDF, cook_val,
+ suffix[i - 1]);
+ else
+ snprintf(tbuf, sizeof(tbuf), CDF, total);
+
+ cook_val = (double)used;
+ i = COOK(cook_val);
+ if (i > 0)
+ snprintf(ubuf, sizeof(ubuf), HDF, cook_val,
+ suffix[i - 1]);
+ else
+ snprintf(ubuf, sizeof(ubuf), CDF, used);
+
+ cook_val = (double)avail;
+ i = COOK(cook_val);
+ if (i > 0)
+ snprintf(abuf, sizeof(abuf), HDF, cook_val,
+ suffix[i - 1]);
+ else
+ snprintf(abuf, sizeof(abuf), CDF, avail);
+ } else {
+ snprintf(tbuf, sizeof(tbuf), CDF, total);
+ snprintf(ubuf, sizeof(tbuf), CDF, used);
+ snprintf(abuf, sizeof(tbuf), CDF, avail);
+ }
+
+ sprintf(rbuf, RDF, ratio);
+ printf(UUF" "CSF" "CSF" "CSF" "RSF" %-s",
+ uuid, tbuf, ubuf, abuf, rbuf, mntdir);
+ if (type)
+ printf("[%s:%d]", type, index);
+
+ if (stat->os_state) {
+ /*
+ * Each character represents the matching
+ * OS_STATE_* bit.
+ */
+ const char state_names[] = "DRSI";
+ __u32 state;
+ __u32 i;
+
+ printf(" ");
+ for (i = 0, state = stat->os_state;
+ state && i < sizeof(state_names); i++) {
+ if (!(state & (1 << i)))
+ continue;
+ printf("%c", state_names[i]);
+ state ^= 1 << i;
+ }
+ }
+
+ printf("\n");
+ break;
+ case -ENODATA:
+ printf(UUF": inactive device\n", uuid);
+ break;
+ default:
+ printf(UUF": %s\n", uuid, strerror(-rc));
+ break;
+ }
+
+ return 0;
+}
+
+struct ll_stat_type {
+ int st_op;
+ char *st_name;
+};
+
+#define LL_STATFS_MAX LOV_MAX_STRIPE_COUNT
+
+struct ll_statfs_data {
+ int sd_index;
+ struct obd_statfs sd_st;
+};
+
+struct ll_statfs_buf {
+ int sb_count;
+ struct ll_statfs_data sb_buf[LL_STATFS_MAX];
+};
+
+static int mntdf(char *mntdir, char *fsname, char *pool, enum mntdf_flags flags,
+ int ops, struct ll_statfs_buf *lsb)
+{
+ struct obd_statfs stat_buf, sum = { .os_bsize = 1 };
+ struct obd_uuid uuid_buf;
+ char *poolname = NULL;
+ struct ll_stat_type types[] = {
+ { .st_op = LL_STATFS_LMV, .st_name = "MDT" },
+ { .st_op = LL_STATFS_LOV, .st_name = "OST" },
+ { .st_name = NULL } };
+ struct ll_stat_type *tp;
+ __u64 ost_ffree = 0;
+ __u32 index;
+ __u32 type;
+ int fd;
+ int rc = 0;
+ int rc2;
+
+ if (pool) {
+ poolname = strchr(pool, '.');
+ if (poolname != NULL) {
+ if (strncmp(fsname, pool, strlen(fsname))) {
+ fprintf(stderr, "filesystem name incorrect\n");
+ return -ENODEV;
+ }
+ poolname++;
+ } else
+ poolname = pool;
+ }
+
+ fd = open(mntdir, O_RDONLY);
+ if (fd < 0) {
+ rc = -errno;
+ fprintf(stderr, "%s: cannot open '%s': %s\n", progname, mntdir,
+ strerror(errno));
+ return rc;
+ }
+
+ if (flags & MNTDF_SHOW) {
+ if (flags & MNTDF_INODES)
+ printf(UUF" "CSF" "CSF" "CSF" "RSF" %-s\n",
+ "UUID", "Inodes", "IUsed", "IFree",
+ "IUse%", "Mounted on");
+ else
+ printf(UUF" "CSF" "CSF" "CSF" "RSF" %-s\n",
+ "UUID",
+ flags & MNTDF_COOKED ? "bytes" : "1K-blocks",
+ "Used", "Available", "Use%", "Mounted on");
+ }
+
+ for (tp = types; tp->st_name != NULL; tp++) {
+ if (!(tp->st_op & ops))
+ continue;
+
+ for (index = 0; ; index++) {
+ memset(&stat_buf, 0, sizeof(struct obd_statfs));
+ memset(&uuid_buf, 0, sizeof(struct obd_uuid));
+ type = flags & MNTDF_LAZY ?
+ tp->st_op | LL_STATFS_NODELAY : tp->st_op;
+ rc2 = llapi_obd_fstatfs(fd, type, index,
+ &stat_buf, &uuid_buf);
+ if (rc2 == -ENODEV)
+ break;
+ if (rc2 == -EAGAIN)
+ continue;
+ if (rc2 == -ENODATA) { /* Inactive device, OK. */
+ if (!(flags & MNTDF_VERBOSE))
+ continue;
+ } else if (rc2 < 0 && rc == 0) {
+ rc = rc2;
+ }
+
+ if (poolname && tp->st_op == LL_STATFS_LOV &&
+ llapi_search_ost(fsname, poolname,
+ obd_uuid2str(&uuid_buf)) != 1)
+ continue;
+
+ /* the llapi_obd_statfs() call may have returned with
+ * an error, but if it filled in uuid_buf we will at
+ * lease use that to print out a message for that OBD.
+ * If we didn't get anything in the uuid_buf, then fill
+ * it in so that we can print an error message. */
+ if (uuid_buf.uuid[0] == '\0')
+ snprintf(uuid_buf.uuid, sizeof(uuid_buf.uuid),
+ "%s%04x", tp->st_name, index);
+ if (!rc && lsb) {
+ lsb->sb_buf[lsb->sb_count].sd_index = index;
+ lsb->sb_buf[lsb->sb_count].sd_st = stat_buf;
+ lsb->sb_count++;
+ }
+ if (flags & MNTDF_SHOW)
+ showdf(mntdir, &stat_buf,
+ obd_uuid2str(&uuid_buf), flags,
+ tp->st_name, index, rc2);
+
+ if (rc2 == 0) {
+ if (tp->st_op == LL_STATFS_LMV) {
+ 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;
+ ost_ffree += stat_buf.os_ffree;
+ }
+ }
+ }
+ }
+
+ close(fd);
+
+ /* 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;
+ }
+ if (flags & MNTDF_SHOW) {
+ printf("\n");
+ showdf(mntdir, &sum, "filesystem_summary:", flags, NULL, 0, 0);
+ printf("\n");
+ }
+
+ return rc;
+}
+
+static int ll_statfs_data_comp(const void *sd1, const void *sd2)
+{
+ const struct obd_statfs *st1 = &((const struct ll_statfs_data *)sd1)->
+ sd_st;
+ const struct obd_statfs *st2 = &((const struct ll_statfs_data *)sd2)->
+ sd_st;
+ int r1 = obd_statfs_ratio(st1);
+ int r2 = obd_statfs_ratio(st2);
+ int64_t result = r1 - r2;
+
+ /* if both space usage are above 90, compare free inodes */
+ if (r1 > 90 && r2 > 90)
+ result = st2->os_ffree - st1->os_ffree;
+
+ if (result < 0)
+ return -1;
+ else if (result == 0)
+ return 0;
+ else
+ return 1;
+}
+
+/* functions */
+static int lfs_setdirstripe(int argc, char **argv)
+{
+ char *dname;
+ int result;
+ struct lfs_setstripe_args lsa = { 0 };
+ struct llapi_stripe_param *param = NULL;
+ __u32 mdts[LMV_MAX_STRIPE_COUNT] = { 0 };
+ char *end;
+ int c;
+ char *mode_opt = NULL;
+ bool default_stripe = false;
+ mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
+ mode_t previous_mode = 0;
+ bool delete = false;
+ struct ll_statfs_buf *lsb = NULL;
+ char mntdir[PATH_MAX] = "";
+ bool auto_distributed = false;
+
+ struct option long_opts[] = {
+ { .val = 'c', .name = "count", .has_arg = required_argument },
+ { .val = 'c', .name = "mdt-count", .has_arg = required_argument },
+ { .val = 'd', .name = "delete", .has_arg = no_argument },
+ { .val = 'D', .name = "default", .has_arg = no_argument },
+ { .val = 'D', .name = "default_stripe", .has_arg = no_argument },
+ { .val = 'H', .name = "mdt-hash", .has_arg = required_argument },
+ { .val = 'i', .name = "mdt-index", .has_arg = required_argument },
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
+ { .val = 'i', .name = "index", .has_arg = required_argument },
+#endif
+ { .val = 'o', .name = "mode", .has_arg = required_argument },
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
+ { .val = 't', .name = "hash-type", .has_arg = required_argument },
+#endif
+ { .val = 'T', .name = "mdt-count", .has_arg = required_argument },
+/* setstripe { .val = 'y', .name = "yaml", .has_arg = no_argument }, */
+ { .name = NULL } };
+
+ setstripe_args_init(&lsa);
+
+ while ((c = getopt_long(argc, argv, "c:dDi:H:m:o:t:T:", long_opts,
+ NULL)) >= 0) {
+ switch (c) {
+ case 0:
+ /* Long options. */
+ break;
+ case 'c':
+ case 'T':
+ lsa.lsa_stripe_count = strtoul(optarg, &end, 0);
+ if (*end != '\0') {
+ fprintf(stderr,
+ "%s %s: invalid stripe count '%s'\n",
+ progname, argv[0], optarg);
+ return CMD_HELP;
+ }
+ break;
+ case 'd':
+ delete = true;
+ default_stripe = true;
+ break;
+ case 'D':
+ default_stripe = true;
+ break;
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
+ case 't':
+ fprintf(stderr, "warning: '--hash-type' and '-t' "
+ "deprecated, use '--mdt-hash' or '-H' instead\n");
+#endif
+ case 'H':
+ lsa.lsa_pattern = check_hashtype(optarg);
+ if (lsa.lsa_pattern == 0) {
+ fprintf(stderr,
+ "%s %s: bad stripe hash type '%s'\n",
+ progname, argv[0], optarg);
+ return CMD_HELP;
+ }
+ break;
+ case 'i':
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
+ if (strcmp(argv[optind - 1], "--index") == 0)
+ fprintf(stderr,
+ "%s %s: warning: '--index' deprecated, use '--mdt-index' instead\n",
+ progname, argv[0]);
+#endif
+ lsa.lsa_nr_tgts = parse_targets(mdts,
+ sizeof(mdts) / sizeof(__u32),
+ lsa.lsa_nr_tgts, optarg);
+ if (lsa.lsa_nr_tgts < 0) {
+ fprintf(stderr,
+ "%s %s: invalid MDT target(s) '%s'\n",
+ progname, argv[0], optarg);
+ return CMD_HELP;
+ }
+
+ lsa.lsa_tgts = mdts;
+ if (lsa.lsa_stripe_off == LLAPI_LAYOUT_DEFAULT)
+ lsa.lsa_stripe_off = mdts[0];
+ break;
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 16, 53, 0)
+ case 'm':
+ fprintf(stderr, "warning: '-m' is deprecated, "
+ "use '--mode' or '-o' instead\n");
+#endif
+ case 'o':
+ mode_opt = optarg;
+ break;
+ default:
+ fprintf(stderr, "%s %s: unrecognized option '%s'\n",
+ progname, argv[0], argv[optind - 1]);
+ return CMD_HELP;
+ }
+ }
+
+ if (optind == argc) {
+ fprintf(stderr, "%s %s: DIR must be specified\n",
+ progname, argv[0]);
+ return CMD_HELP;
+ }
+
+ if (!delete && lsa.lsa_stripe_off == LLAPI_LAYOUT_DEFAULT &&
+ lsa.lsa_stripe_count == LLAPI_LAYOUT_DEFAULT) {
+ fprintf(stderr,
+ "%s %s: stripe offset and count must be specified\n",
+ progname, argv[0]);
+ return CMD_HELP;
}
if (delete &&
previous_mode = umask(0);
}
- /* initialize stripe parameters */
- param = calloc(1, offsetof(typeof(*param), lsp_osts[lsa.lsa_nr_tgts]));
+ /*
+ * initialize stripe parameters, in case param is converted to specific,
+ * i.e, 'lfs mkdir -i -1 -c N', always allocate space for lsp_tgts.
+ */
+ param = calloc(1, offsetof(typeof(*param),
+ lsp_tgts[lsa.lsa_stripe_count != LLAPI_LAYOUT_DEFAULT ?
+ lsa.lsa_stripe_count : lsa.lsa_nr_tgts]));
if (param == NULL) {
fprintf(stderr,
"%s %s: cannot allocate memory for parameters: %s\n",
dname = argv[optind];
do {
- if (default_stripe)
+ if (default_stripe) {
result = llapi_dir_set_default_lmv(dname, param);
- else
- result = llapi_dir_create_param(dname, mode, param);
-
- if (result) {
- fprintf(stderr,
- "%s setdirstripe: cannot create stripe dir '%s': %s\n",
- progname, dname, strerror(-result));
- break;
- }
- dname = argv[++optind];
- } while (dname != NULL);
-
- if (mode_opt != NULL)
- umask(previous_mode);
-
- free(param);
- return result;
-}
-
-/* functions */
-static int lfs_rmentry(int argc, char **argv)
-{
- char *dname;
- int index;
- int result = 0;
-
- if (argc <= 1) {
- fprintf(stderr, "error: %s: missing dirname\n",
- argv[0]);
- return CMD_HELP;
- }
-
- index = 1;
- dname = argv[index];
- while (dname != NULL) {
- result = llapi_direntry_remove(dname);
- if (result) {
- fprintf(stderr, "error: %s: remove dir entry '%s' "
- "failed\n", argv[0], dname);
- break;
- }
- dname = argv[++index];
- }
- return result;
-}
-
-static int lfs_mv(int argc, char **argv)
-{
- struct find_param param = {
- .fp_max_depth = -1,
- .fp_mdt_index = -1,
- };
- char *end;
- int c;
- int rc = 0;
- struct option long_opts[] = {
- { .val = 'm', .name = "mdt-index", .has_arg = required_argument },
- { .val = 'v', .name = "verbose", .has_arg = no_argument },
- { .name = NULL } };
-
- while ((c = getopt_long(argc, argv, "m:M:v", long_opts, NULL)) != -1) {
- switch (c) {
-#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
- case 'M':
- fprintf(stderr, "warning: '-M' deprecated"
- ", use '--mdt-index' or '-m' instead\n");
-#endif
- case 'm':
- param.fp_mdt_index = 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.fp_verbose = VERBOSE_DETAIL;
- break;
- default:
- fprintf(stderr, "error: %s: unrecognized option '%s'\n",
- argv[0], argv[optind - 1]);
- return CMD_HELP;
- }
- }
-
- if (param.fp_mdt_index == -1) {
- fprintf(stderr, "%s: MDT index must be specified\n", argv[0]);
- return CMD_HELP;
- }
-
- if (optind >= argc) {
- fprintf(stderr, "%s: missing operand path\n", argv[0]);
- return CMD_HELP;
- }
-
- param.fp_migrate = 1;
- rc = llapi_migrate_mdt(argv[optind], ¶m);
- if (rc != 0)
- fprintf(stderr, "%s: cannot migrate '%s' to MDT%04x: %s\n",
- argv[0], argv[optind], param.fp_mdt_index,
- strerror(-rc));
- return rc;
-}
-
-static int lfs_osts(int argc, char **argv)
-{
- return lfs_tgts(argc, argv);
-}
-
-static int lfs_mdts(int argc, char **argv)
-{
- return lfs_tgts(argc, argv);
-}
-
-#define COOK(value) \
-({ \
- int radix = 0; \
- while (value > 1024) { \
- value /= 1024; \
- radix++; \
- } \
- radix; \
-})
-#define UUF "%-20s"
-#define CSF "%11s"
-#define CDF "%11llu"
-#define HDF "%8.1f%c"
-#define RSF "%4s"
-#define RDF "%3d%%"
-
-enum mntdf_flags {
- MNTDF_INODES = 0x0001,
- MNTDF_COOKED = 0x0002,
- MNTDF_LAZY = 0x0004,
- MNTDF_VERBOSE = 0x0008,
-};
-
-static int showdf(char *mntdir, struct obd_statfs *stat,
- char *uuid, enum mntdf_flags flags,
- char *type, int index, int rc)
-{
- long long avail, used, total;
- double ratio = 0;
- char *suffix = "KMGTPEZY";
- /* Note if we have >2^64 bytes/fs these buffers will need to be grown */
- char tbuf[3 * sizeof(__u64)];
- char ubuf[3 * sizeof(__u64)];
- char abuf[3 * sizeof(__u64)];
- char rbuf[3 * sizeof(__u64)];
-
- if (!uuid || !stat)
- return -EINVAL;
-
- switch (rc) {
- case 0:
- if (flags & MNTDF_INODES) {
- avail = stat->os_ffree;
- used = stat->os_files - stat->os_ffree;
- total = stat->os_files;
} else {
- int shift = flags & MNTDF_COOKED ? 0 : 10;
-
- avail = (stat->os_bavail * stat->os_bsize) >> shift;
- used = ((stat->os_blocks - stat->os_bfree) *
- stat->os_bsize) >> shift;
- total = (stat->os_blocks * stat->os_bsize) >> shift;
- }
+ /* if current \a dname isn't under the same \a mntdir
+ * as the last one, and the last one was
+ * auto-distributed, restore \a param.
+ */
+ if (mntdir[0] != '\0' &&
+ strncmp(dname, mntdir, strlen(mntdir)) &&
+ auto_distributed) {
+ param->lsp_is_specific = false;
+ param->lsp_stripe_offset = -1;
+ auto_distributed = false;
+ }
+
+ if (!param->lsp_is_specific &&
+ param->lsp_stripe_offset == -1) {
+ char path[PATH_MAX] = "";
+
+ if (!lsb) {
+ lsb = malloc(sizeof(*lsb));
+ if (!lsb) {
+ result = -ENOMEM;
+ break;
+ }
+ }
+ lsb->sb_count = 0;
- if ((used + avail) > 0)
- ratio = (double)used / (double)(used + avail);
+ /* use mntdir for dirname() temporarily */
+ strncpy(mntdir, dname, sizeof(mntdir));
+ if (!realpath(dirname(mntdir), path)) {
+ result = -errno;
+ fprintf(stderr,
+ "error: invalid path '%s': %s\n",
+ argv[optind], strerror(errno));
+ break;
+ }
+ mntdir[0] = '\0';
- if (flags & MNTDF_COOKED) {
- int i;
- double cook_val;
+ result = llapi_search_mounts(path, 0, mntdir,
+ NULL);
+ if (result < 0 || mntdir[0] == '\0') {
+ fprintf(stderr,
+ "No suitable Lustre mount found\n");
+ break;
+ }
- cook_val = (double)total;
- i = COOK(cook_val);
- if (i > 0)
- snprintf(tbuf, sizeof(tbuf), HDF, cook_val,
- suffix[i - 1]);
- else
- snprintf(tbuf, sizeof(tbuf), CDF, total);
+ result = mntdf(mntdir, NULL, NULL, 0,
+ LL_STATFS_LMV, lsb);
+ if (result < 0)
+ break;
- cook_val = (double)used;
- i = COOK(cook_val);
- if (i > 0)
- snprintf(ubuf, sizeof(ubuf), HDF, cook_val,
- suffix[i - 1]);
- else
- snprintf(ubuf, sizeof(ubuf), CDF, used);
+ if (param->lsp_stripe_count > lsb->sb_count) {
+ fprintf(stderr,
+ "error: stripe count %d is too big\n",
+ param->lsp_stripe_count);
+ result = -ERANGE;
+ break;
+ }
- cook_val = (double)avail;
- i = COOK(cook_val);
- if (i > 0)
- snprintf(abuf, sizeof(abuf), HDF, cook_val,
- suffix[i - 1]);
- else
- snprintf(abuf, sizeof(abuf), CDF, avail);
- } else {
- snprintf(tbuf, sizeof(tbuf), CDF, total);
- snprintf(ubuf, sizeof(tbuf), CDF, used);
- snprintf(abuf, sizeof(tbuf), CDF, avail);
- }
+ qsort(lsb->sb_buf, lsb->sb_count,
+ sizeof(struct ll_statfs_data),
+ ll_statfs_data_comp);
- sprintf(rbuf, RDF, (int)(ratio * 100 + 0.5));
- printf(UUF" "CSF" "CSF" "CSF" "RSF" %-s",
- uuid, tbuf, ubuf, abuf, rbuf, mntdir);
- if (type)
- printf("[%s:%d]", type, index);
+ auto_distributed = true;
+ }
- if (stat->os_state) {
- /*
- * Each character represents the matching
- * OS_STATE_* bit.
- */
- const char state_names[] = "DRSI";
- __u32 state;
- __u32 i;
+ if (auto_distributed) {
+ int r;
+ int nr = MAX(param->lsp_stripe_count,
+ lsb->sb_count / 2);
- printf(" ");
- for (i = 0, state = stat->os_state;
- state && i < sizeof(state_names); i++) {
- if (!(state & (1 << i)))
- continue;
- printf("%c", state_names[i]);
- state ^= 1 << i;
+ /* don't use server whose usage is above 90% */
+ while (nr != param->lsp_stripe_count &&
+ obd_statfs_ratio(&lsb->sb_buf[nr].sd_st)
+ > 90)
+ nr = MAX(param->lsp_stripe_count,
+ nr / 2);
+
+ /* get \a r between [0, nr) */
+ r = rand() % nr;
+
+ param->lsp_stripe_offset =
+ lsb->sb_buf[r].sd_index;
+ if (param->lsp_stripe_count > 1) {
+ int i = 0;
+
+ param->lsp_is_specific = true;
+ for (; i < param->lsp_stripe_count; i++)
+ param->lsp_tgts[(i + r) % nr] =
+ lsb->sb_buf[i].sd_index;
+ }
}
+
+ result = llapi_dir_create(dname, mode, param);
}
- printf("\n");
- break;
- case -ENODATA:
- printf(UUF": inactive device\n", uuid);
- break;
- default:
- printf(UUF": %s\n", uuid, strerror(-rc));
- break;
- }
+ if (result) {
+ fprintf(stderr,
+ "%s setdirstripe: cannot create stripe dir '%s': %s\n",
+ progname, dname, strerror(-result));
+ break;
+ }
+ dname = argv[++optind];
+ } while (dname != NULL);
- return 0;
-}
+ if (mode_opt != NULL)
+ umask(previous_mode);
-struct ll_stat_type {
- int st_op;
- char *st_name;
-};
+ free(lsb);
+ free(param);
+ return result;
+}
-static int mntdf(char *mntdir, char *fsname, char *pool, enum mntdf_flags flags)
+/* functions */
+static int lfs_rmentry(int argc, char **argv)
{
- struct obd_statfs stat_buf, sum = { .os_bsize = 1 };
- struct obd_uuid uuid_buf;
- char *poolname = NULL;
- struct ll_stat_type types[] = {
- { .st_op = LL_STATFS_LMV, .st_name = "MDT" },
- { .st_op = LL_STATFS_LOV, .st_name = "OST" },
- { .st_name = NULL } };
- struct ll_stat_type *tp;
- __u64 ost_ffree = 0;
- __u32 index;
- __u32 type;
- int fd;
- int rc = 0;
- int rc2;
+ char *dname;
+ int index;
+ int result = 0;
- if (pool) {
- poolname = strchr(pool, '.');
- if (poolname != NULL) {
- if (strncmp(fsname, pool, strlen(fsname))) {
- fprintf(stderr, "filesystem name incorrect\n");
- return -ENODEV;
- }
- poolname++;
- } else
- poolname = pool;
+ if (argc <= 1) {
+ fprintf(stderr, "error: %s: missing dirname\n",
+ argv[0]);
+ return CMD_HELP;
}
- fd = open(mntdir, O_RDONLY);
- if (fd < 0) {
- rc = -errno;
- fprintf(stderr, "%s: cannot open '%s': %s\n", progname, mntdir,
- strerror(errno));
- return rc;
+ index = 1;
+ dname = argv[index];
+ while (dname != NULL) {
+ result = llapi_direntry_remove(dname);
+ if (result) {
+ fprintf(stderr, "error: %s: remove dir entry '%s' "
+ "failed\n", argv[0], dname);
+ break;
+ }
+ dname = argv[++index];
}
+ return result;
+}
- if (flags & MNTDF_INODES)
- printf(UUF" "CSF" "CSF" "CSF" "RSF" %-s\n",
- "UUID", "Inodes", "IUsed", "IFree",
- "IUse%", "Mounted on");
- else
- printf(UUF" "CSF" "CSF" "CSF" "RSF" %-s\n",
- "UUID", flags & MNTDF_COOKED ? "bytes" : "1K-blocks",
- "Used", "Available", "Use%", "Mounted on");
-
- for (tp = types; tp->st_name != NULL; tp++) {
- for (index = 0; ; index++) {
- memset(&stat_buf, 0, sizeof(struct obd_statfs));
- memset(&uuid_buf, 0, sizeof(struct obd_uuid));
- type = flags & MNTDF_LAZY ?
- tp->st_op | LL_STATFS_NODELAY : tp->st_op;
- rc2 = llapi_obd_fstatfs(fd, type, index,
- &stat_buf, &uuid_buf);
- if (rc2 == -ENODEV)
- break;
- if (rc2 == -EAGAIN)
- continue;
- if (rc2 == -ENODATA) { /* Inactive device, OK. */
- if (!(flags & MNTDF_VERBOSE))
- continue;
- } else if (rc2 < 0 && rc == 0) {
- rc = rc2;
- }
-
- if (poolname && tp->st_op == LL_STATFS_LOV &&
- llapi_search_ost(fsname, poolname,
- obd_uuid2str(&uuid_buf)) != 1)
- continue;
-
- /* the llapi_obd_statfs() call may have returned with
- * an error, but if it filled in uuid_buf we will at
- * lease use that to print out a message for that OBD.
- * If we didn't get anything in the uuid_buf, then fill
- * it in so that we can print an error message. */
- if (uuid_buf.uuid[0] == '\0')
- snprintf(uuid_buf.uuid, sizeof(uuid_buf.uuid),
- "%s%04x", tp->st_name, index);
- showdf(mntdir, &stat_buf, obd_uuid2str(&uuid_buf),
- flags, tp->st_name, index, rc2);
+static int lfs_mv(int argc, char **argv)
+{
+ struct find_param param = {
+ .fp_max_depth = -1,
+ .fp_mdt_index = -1,
+ };
+ char *end;
+ int c;
+ int rc = 0;
+ struct option long_opts[] = {
+ { .val = 'm', .name = "mdt-index", .has_arg = required_argument },
+ { .val = 'v', .name = "verbose", .has_arg = no_argument },
+ { .name = NULL } };
- if (rc2 == 0) {
- if (tp->st_op == LL_STATFS_LMV) {
- 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;
- ost_ffree += stat_buf.os_ffree;
- }
+ while ((c = getopt_long(argc, argv, "m:M:v", long_opts, NULL)) != -1) {
+ switch (c) {
+#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(3, 0, 53, 0)
+ case 'M':
+ fprintf(stderr, "warning: '-M' deprecated"
+ ", use '--mdt-index' or '-m' instead\n");
+#endif
+ case 'm':
+ param.fp_mdt_index = 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.fp_verbose = VERBOSE_DETAIL;
+ break;
+ default:
+ fprintf(stderr, "error: %s: unrecognized option '%s'\n",
+ argv[0], argv[optind - 1]);
+ return CMD_HELP;
}
}
- close(fd);
+ if (param.fp_mdt_index == -1) {
+ fprintf(stderr, "%s: MDT index must be specified\n", argv[0]);
+ return CMD_HELP;
+ }
- /* 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;
+ if (optind >= argc) {
+ fprintf(stderr, "%s: missing operand path\n", argv[0]);
+ return CMD_HELP;
}
- printf("\n");
- showdf(mntdir, &sum, "filesystem_summary:", flags, NULL, 0, 0);
- printf("\n");
+ param.fp_migrate = 1;
+ rc = llapi_migrate_mdt(argv[optind], ¶m);
+ if (rc != 0)
+ fprintf(stderr, "%s: cannot migrate '%s' to MDT%04x: %s\n",
+ argv[0], argv[optind], param.fp_mdt_index,
+ strerror(-rc));
return rc;
}
+static int lfs_osts(int argc, char **argv)
+{
+ return lfs_tgts(argc, argv);
+}
+
+static int lfs_mdts(int argc, char **argv)
+{
+ return lfs_tgts(argc, argv);
+}
+
static int lfs_df(int argc, char **argv)
{
char mntdir[PATH_MAX] = {'\0'}, path[PATH_MAX] = {'\0'};
- enum mntdf_flags flags = 0;
+ enum mntdf_flags flags = MNTDF_SHOW;
+ int ops = LL_STATFS_LMV | LL_STATFS_LOV;
int c, rc = 0, index = 0;
char fsname[PATH_MAX] = "", *pool_name = NULL;
struct option long_opts[] = {
if (mntdir[0] == '\0')
continue;
- rc = mntdf(mntdir, fsname, pool_name, flags);
+ rc = mntdf(mntdir, fsname, pool_name, flags, ops, NULL);
if (rc || path[0] != '\0')
break;
fsname[0] = '\0'; /* avoid matching in next loop */
break;
case 'o':
valid = qctl.qc_valid = QC_UUID;
- strlcpy(obd_uuid, optarg, sizeof(qctl.obd_uuid));
+ snprintf(obd_uuid, sizeof(qctl.obd_uuid), "%s", optarg);
break;
case 'i':
valid = qctl.qc_valid = QC_MDTIDX;
if (rc1 && !rc)
rc = rc1;
}
+ return rc;
/* lfs quota -u username /path/to/lustre/mount */
} else if (qctl.qc_cmd == LUSTRE_Q_GETQUOTA) {
/* options should be followed by u/g-name and mntpoint */
return CMD_HELP;
}
}
- mnt = argv[optind];
- rc = get_print_quota(mnt, name, &qctl, verbose, quiet,
- human_readable);
} else if (optind + 1 != argc || qctl.qc_type == ALLQUOTA) {
fprintf(stderr, "%s quota: missing quota info argument(s)\n",
progname);
return CMD_HELP;
}
+ mnt = argv[optind];
+ rc = get_print_quota(mnt, name, &qctl, verbose, quiet,
+ human_readable);
return rc;
}
#endif /* HAVE_SYS_QUOTA_H! */
case 'f':
follow++;
break;
- case '?':
- return CMD_HELP;
default:
- fprintf(stderr, "error: %s: option '%s' unrecognized\n",
- argv[0], argv[optind - 1]);
+ fprintf(stderr,
+ "%s changelog: unrecognized option '%s'\n",
+ progname, argv[optind - 1]);
return CMD_HELP;
}
}
- if (optind >= argc)
- return CMD_HELP;
+ if (optind >= argc) {
+ fprintf(stderr, "%s changelog: mdtname must be specified\n",
+ progname);
+ return CMD_HELP;
+ }
mdd = argv[optind++];
if (argc > optind)
(follow ? CHANGELOG_FLAG_FOLLOW : 0),
mdd, startrec);
if (rc < 0) {
- fprintf(stderr, "Can't start changelog: %s\n",
- strerror(errno = -rc));
+ fprintf(stderr, "%s changelog: cannot start changelog: %s\n",
+ progname, strerror(errno = -rc));
return rc;
}
CHANGELOG_EXTRA_FLAG_OMODE |
CHANGELOG_EXTRA_FLAG_XATTR);
if (rc < 0) {
- fprintf(stderr, "Can't set xflags for changelog: %s\n",
- strerror(errno = -rc));
+ fprintf(stderr,
+ "%s changelog: cannot set xflags for changelog: %s\n",
+ progname, strerror(errno = -rc));
return rc;
}
if (omd->cr_openflags & MDS_FMODE_EXEC) {
mode[2] = 'x';
} else {
- if (omd->cr_openflags & FMODE_READ)
+ if (omd->cr_openflags & MDS_FMODE_READ)
mode[0] = 'r';
if (omd->cr_openflags &
- (FMODE_WRITE |
+ (MDS_FMODE_WRITE |
MDS_OPEN_TRUNC |
MDS_OPEN_APPEND))
mode[1] = 'w';
printf("\n");
llapi_changelog_free(&rec);
- }
+ }
- llapi_changelog_fini(&changelog_priv);
+ llapi_changelog_fini(&changelog_priv);
- if (rc < 0)
- fprintf(stderr, "Changelog: %s\n", strerror(errno = -rc));
+ if (rc < 0)
+ fprintf(stderr, "%s changelog: cannot access changelog: %s\n",
+ progname, strerror(errno = -rc));
- return (rc == 1 ? 0 : rc);
+ return (rc == 1 ? 0 : rc);
}
static int lfs_changelog_clear(int argc, char **argv)
goto error;
}
- ioc->lil_mode = LL_LEASE_WRLCK;
- ioc->lil_flags = LL_LEASE_RESYNC;
- rc = llapi_lease_set(fd, ioc);
- if (rc < 0) {
- fprintf(stderr,
- "%s: '%s' llapi_lease_set resync failed: %s.\n",
- progname, fname, strerror(errno));
- goto close_fd;
- }
-
layout = llapi_layout_get_by_fd(fd, 0);
if (layout == NULL) {
fprintf(stderr, "%s: '%s' llapi_layout_get_by_fd failed: %s.\n",
fprintf(stderr, "%s: '%s' llapi_layout_flags_get failed: %s.\n",
progname, fname, strerror(errno));
rc = -errno;
- goto close_fd;
+ goto free_layout;
}
flr_state &= LCM_FL_FLR_MASK;
- switch (flr_state) {
- case LCM_FL_NONE:
+ if (flr_state == LCM_FL_NONE) {
rc = -EINVAL;
- case LCM_FL_RDONLY:
- fprintf(stderr, "%s: '%s' file state error: %s\n", progname,
- fname, llapi_layout_flags_string(flr_state));
- goto close_fd;
- default:
- break;
+ fprintf(stderr, "%s: '%s' is not a FLR file.\n",
+ progname, fname);
+ goto free_layout;
}
/* get stale component info */
comp_size = llapi_mirror_find_stale(layout, comp_array,
ARRAY_SIZE(comp_array),
mirror_ids, ids_nr);
- if (comp_size < 0) {
+ if (comp_size <= 0) {
rc = comp_size;
- goto close_fd;
+ goto free_layout;
+ }
+
+ ioc->lil_mode = LL_LEASE_WRLCK;
+ ioc->lil_flags = LL_LEASE_RESYNC;
+ rc = llapi_lease_set(fd, ioc);
+ if (rc < 0) {
+ if (rc == -EALREADY)
+ rc = 0;
+ else
+ fprintf(stderr,
+ "%s: '%s' llapi_lease_get_ext resync failed: %s.\n",
+ progname, fname, strerror(errno));
+ goto free_layout;
}
idx = 0;
if (rc != LL_LEASE_WRLCK) {
fprintf(stderr, "%s: '%s' lost lease lock.\n",
progname, fname);
- goto close_fd;
+ goto free_layout;
}
mirror_id = comp_array[idx].lrc_mirror_id;
fprintf(stderr, "%s: '%s' llapi_mirror_resync_one: "
"%ld.\n", progname, fname, result);
rc = result;
- goto close_fd;
+ goto unlock;
} else if (result > 0) {
int j;
idx = i;
}
+unlock:
/* prepare ioc for lease put */
ioc->lil_mode = LL_LEASE_UNLCK;
ioc->lil_flags = LL_LEASE_RESYNC_DONE;
}
}
- llapi_layout_free(layout);
-
rc = llapi_lease_set(fd, ioc);
if (rc <= 0) {
if (rc == 0) /* lost lease lock */
rc = -EBUSY;
fprintf(stderr, "%s: resync file '%s' failed: %s.\n",
progname, fname, strerror(errno));
- goto close_fd;
+ goto free_layout;
}
/**
* llapi_lease_set returns lease mode when it request to unlock
*/
rc = 0;
+free_layout:
+ llapi_layout_free(layout);
close_fd:
close(fd);
error: