X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Futils%2Flfs.c;h=79d34a6d9c6a240b4fac4999b660fc778c1a0132;hb=8ae646b1bd11066fef65d7fac18621946ddff6da;hp=62f919871b2ba12cc6adc53af4092b56ec617cee;hpb=253cc7ae49f89bba919a5a570209e2629b3843c6;p=fs%2Flustre-release.git diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 62f9198..79d34a6 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include @@ -147,6 +148,7 @@ enum setstripe_origin { SO_MIRROR_CREATE, SO_MIRROR_EXTEND, SO_MIRROR_SPLIT, + SO_MIRROR_DELETE, }; static int lfs_setstripe_internal(int argc, char **argv, enum setstripe_origin opc); @@ -171,6 +173,10 @@ static inline int lfs_mirror_split(int argc, char **argv) { return lfs_setstripe_internal(argc, argv, SO_MIRROR_SPLIT); } +static inline int lfs_mirror_delete(int argc, char **argv) +{ + return lfs_setstripe_internal(argc, argv, SO_MIRROR_DELETE); +} /* Setstripe and migrate share mostly the same parameters */ #define SSM_CMD_COMMON(cmd) \ @@ -180,16 +186,17 @@ static inline int lfs_mirror_split(int argc, char **argv) " [--stripe-index|-i ]\n" \ " [--stripe-size|-S ]\n" \ " [--layout|-L ]\n" \ - " [--pool|-p ]\n" \ + " [--mirror_count|-N[mirror_count]]\n" \ " [--ost|-o ]\n" \ + " [--pool|-p ]\n" \ " [--yaml|-y ]\n" \ " [--copy=]\n" #define SSM_HELP_COMMON \ "\tstripe_count: Number of OSTs to stripe over (0=fs default, -1 all)\n" \ "\t Using -C instead of -c allows overstriping, which\n" \ - "\t will place more than one stripe per OST if\n" \ - "\t stripe_count is greater than the number of OSTs\n" \ + "\t will place more than one stripe per OST if\n" \ + "\t stripe_count is greater than the number of OSTs\n" \ "\tstart_ost_idx: OST index of first stripe (-1=default round robin)\n"\ "\tstripe_size: Number of bytes on each OST (0=fs default)\n" \ "\t Can be specified with K, M or G (for KB, MB, GB\n" \ @@ -201,7 +208,7 @@ static inline int lfs_mirror_split(int argc, char **argv) "\t -o ,-,\n" \ "\t Or:\n" \ "\t -o -o - -o \n" \ - "\t If --pool is set with --ost, then the OSTs\n" \ + "\t If --pool is set with --ost then the OSTs\n" \ "\t must be the members of the pool.\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" \ @@ -221,7 +228,7 @@ static inline int lfs_mirror_split(int argc, char **argv) "\t it must follow the option without a space.\n" \ "\t The option can also be repeated multiple times to\n" \ "\t separate mirrors that have different layouts.\n" \ - "\tsetstripe options: Mirror layout\n" \ + "\tSETSTRIPE_OPTIONS: Mirror layout as with 'setstripe'\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" \ @@ -238,8 +245,8 @@ static inline int lfs_mirror_split(int argc, char **argv) "\t file.\n" #define MIRROR_EXTEND_USAGE \ - " <--mirror-count|-N[mirror_count]>\n" \ - " [setstripe options|-f ]\n" \ + " {--mirror-count|-N[mirror_count]}\n" \ + " [SETSTRIPE_OPTIONS|-f|--file ]\n" \ " [--no-verify]\n" #define SETSTRIPE_USAGE \ @@ -276,7 +283,7 @@ static inline int lfs_mirror_split(int argc, char **argv) "\tmode: the file access permission of the directory (octal)\n" \ "To create dir with a foreign (free format) layout :\n" \ "setdirstripe|mkdir --foreign[=] -x|-xattr " \ - "[--mode|-m mode] [--flags ] \n" \ + "[--mode|-o mode] [--flags ] \n" \ "\tmode: the mode of the directory\n" \ "\tforeign_type: none or daos\n" @@ -288,19 +295,23 @@ command_t mirror_cmdlist[] = { .pc_help = "Create a mirrored file.\n" "usage: lfs mirror create " "<--mirror-count|-N[mirror_count]> " - "[setstripe options] ... \n" + "[SETSTRIPE_OPTIONS] ... ...\n" MIRROR_CREATE_HELP }, + { .pc_name = "delete", .pc_func = lfs_mirror_delete, + .pc_help = "delete a mirror from a file.\n" + "usage: lfs mirror delete {--comp-id|-I |-p } ...\n" + }, { .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|-f ] ... \n" + "[SETSTRIPE_OPTIONS|-f ] ... ...\n" MIRROR_EXTEND_HELP }, { .pc_name = "split", .pc_func = lfs_mirror_split, .pc_help = "Split a mirrored file.\n" "usage: lfs mirror split <--mirror-id |\n" "\t <--component-id|-I |-p > [--destroy|-d]\n" - "\t [-f ] \n" + "\t [-f ] ...\n" "\tmirror_id: The numerical unique identifier for a mirror. It\n" "\t can be fetched by lfs getstripe command.\n" "\tcomp_id: Unique component ID within a mirror.\n" @@ -382,10 +393,10 @@ command_t cmdlist[] = { SSM_CMD_COMMON("setstripe --component-add") SSM_HELP_COMMON "To totally delete the default striping from an existing directory:\n" - "usage: setstripe -d \n" + "usage: setstripe [--delete|-d] \n" " or\n" "To create a mirrored file or set s default mirror layout on a directory:\n" - "usage: setstripe -N[mirror_count] [STRIPE_OPTIONS] \n" + "usage: setstripe {--mirror-count|-N}[mirror_count] [SETSTRIPE_OPTIONS] \n" " or\n" "To delete the last component(s) from an existing composite file\n" "(note that this will also delete any data in those components):\n" @@ -448,6 +459,7 @@ command_t cmdlist[] = { "usage: find ...\n" " [[!] --atime|-A [+-]N[smhdwy]] [[!] --ctime|-C [+-]N[smhdwy]]\n" " [[!] --mtime|-M [+-]N[smhdwy]] [[!] --blocks|-b N]\n" + " [[!] --newer[XY] ]\n" " [--maxdepth|-D N] [[!] --mdt-index|--mdt|-m ]\n" " [[!] --name|-n ] [[!] --ost|-O ]\n" " [--print|-P] [--print0|-0] [[!] --size|-s [+-]N[bkMGTPE]]\n" @@ -463,7 +475,7 @@ command_t cmdlist[] = { " [[!] --component-count [+-]]\n" " [[!] --component-start [+-]N[kMGTPE]]\n" " [[!] --component-end|-E [+-]N[kMGTPE]]\n" - " [[!] --component-flags ]\n" + " [[!] --component-flags {init,stale,prefer,offline,nosync,extension}]\n" " [[!] --mirror-count|-N [+-]]\n" " [[!] --mirror-state <[^]state>]\n" " [[!] --mdt-count|-T [+-]]\n" @@ -486,7 +498,8 @@ command_t cmdlist[] = { {"df", lfs_df, 0, "report filesystem disk space usage or inodes usage " "of each MDS and all OSDs or a batch belonging to a specific pool.\n" - "Usage: df [-i] [-h] [--lazy|-l] [--pool|-p [.] [path]"}, + "Usage: df [--inodes|-i] [--human-readable|-h] [--lazy|-l]\n" + " [--pool|-p [.]] [path]"}, {"getname", lfs_getname, 0, "list instances and specified mount points [for specified path only]\n" "Usage: getname [--help|-h] [--instance|-i] [--fsname|-n] [path ...]"}, @@ -501,8 +514,8 @@ command_t cmdlist[] = { " [--inode-softlimit ]\n" " [--inode-hardlimit ] \n" " setquota [-t] <-u|--user|-g|--group|-p|--projid>\n" - " [--block-grace ]\n" - " [--inode-grace ] \n" + " [--block-grace 'notify'|]\n" + " [--inode-grace 'notify'|] \n" " setquota <-U|-G|-P>\n" " -b -B \n" " -i -I \n" @@ -525,8 +538,11 @@ command_t cmdlist[] = { " Quota space rebalancing process will stop when this mininum\n" " value is reached. As a result, quota exceeded can be returned\n" " while many targets still have 1MB or 1K inodes of spare\n" - " quota space."}, - {"quota", lfs_quota, 0, "Display disk usage and limits.\n" + " quota space.\n\n" + " When setting the grace time, 'notify' can be used as grace to\n" + " be notified after the quota is over soft limit but prevents\n" + " the soft limit from becoming the hard limit."}, + {"quota", lfs_quota, 0, "Display disk usage and limits.\n" "usage: quota [-q] [-v] [-h] [-o |-i |-I " "]\n" " [<-u|-g|-p> ||||] \n" @@ -563,7 +579,7 @@ command_t cmdlist[] = { {"rmfid", lfs_rmfid, 0, "Remove file(s) by FID(s)\n" "usage: rmfid ..."}, {"data_version", lfs_data_version, 0, "Display file data version for " - "a given path.\n" "usage: data_version -[n|r|w] "}, + "a given path.\n" "usage: data_version [-n|-r|-w] "}, {"hsm_state", lfs_hsm_state, 0, "Display the HSM information (states, " "undergoing actions) for given files.\n usage: hsm_state ..."}, {"hsm_set", lfs_hsm_set, 0, "Set HSM user flag on specified files.\n" @@ -701,9 +717,6 @@ static int check_hashtype(const char *hashtype) if (strcmp(hashtype, mdt_hash_name[i]) == 0) return i; - if (!strcmp(hashtype, LMV_HASH_NAME_SPACE)) - return LMV_HASH_TYPE_DEFAULT | LMV_HASH_FLAG_SPACE; - return 0; } @@ -808,12 +821,12 @@ migrate_open_files(const char *name, __u64 migration_flags, } /* create, open a volatile file, use caching (ie no directio) */ - if (param != NULL) - fdv = llapi_file_open_param(volatile_file, open_flags, - open_mode, param); - else + if (layout) fdv = lfs_component_create(volatile_file, open_flags, open_mode, layout); + else + fdv = llapi_file_open_param(volatile_file, open_flags, + open_mode, param); } while (fdv < 0 && (rc = fdv) == -EEXIST); if (rc < 0) { @@ -2424,14 +2437,14 @@ new_comp: if (lsa->lsa_stripe_count != LLAPI_LAYOUT_DEFAULT) { fprintf(stderr, "Option 'stripe-count' can't be " "specified with Data-on-MDT component: %lld\n", - (long long)lsa->lsa_stripe_count); + lsa->lsa_stripe_count); errno = EINVAL; return -1; } if (lsa->lsa_stripe_size != LLAPI_LAYOUT_DEFAULT) { fprintf(stderr, "Option 'stripe-size' can't be " "specified with Data-on-MDT component: %llu\n", - (unsigned long long)lsa->lsa_stripe_size); + lsa->lsa_stripe_size); errno = EINVAL; return -1; } @@ -2445,7 +2458,7 @@ new_comp: if (lsa->lsa_stripe_off != LLAPI_LAYOUT_DEFAULT) { fprintf(stderr, "Option 'stripe-offset' can't be " "specified with Data-on-MDT component: %lld\n", - (long long)lsa->lsa_stripe_off); + lsa->lsa_stripe_off); errno = EINVAL; return -1; } @@ -2460,7 +2473,7 @@ new_comp: rc = llapi_layout_pattern_set(layout, lsa->lsa_pattern); if (rc) { fprintf(stderr, "Set stripe pattern %#llx failed. %s\n", - (unsigned long long)lsa->lsa_pattern, + lsa->lsa_pattern, strerror(errno)); return rc; } @@ -2470,7 +2483,7 @@ new_comp: rc = llapi_layout_pattern_set(layout, lsa->lsa_pattern); if (rc) { fprintf(stderr, "Set stripe pattern %#llx failed. %s\n", - (unsigned long long)lsa->lsa_pattern, + lsa->lsa_pattern, strerror(errno)); return rc; } @@ -2493,7 +2506,7 @@ new_comp: rc = llapi_layout_stripe_count_set(layout, lsa->lsa_stripe_count); if (rc) { fprintf(stderr, "Set stripe count %lld failed: %s\n", - (long long)lsa->lsa_stripe_count, strerror(errno)); + lsa->lsa_stripe_count, strerror(errno)); return rc; } @@ -2519,7 +2532,7 @@ new_comp: lsa->lsa_stripe_count != LLAPI_LAYOUT_WIDE && lsa->lsa_nr_tgts != lsa->lsa_stripe_count) { fprintf(stderr, "stripe_count(%lld) != nr_tgts(%d)\n", - (long long)lsa->lsa_stripe_count, + lsa->lsa_stripe_count, lsa->lsa_nr_tgts); errno = EINVAL; return -1; @@ -2970,6 +2983,7 @@ enum { LFS_MIRROR_INDEX_OPT, LFS_LAYOUT_FOREIGN_OPT, LFS_MODE_OPT, + LFS_NEWERXY_OPT, }; /* functions */ @@ -3113,6 +3127,10 @@ static int lfs_setstripe_internal(int argc, char **argv, migrate_mode = (opc == SO_MIGRATE); mirror_mode = (opc == SO_MIRROR_CREATE || opc == SO_MIRROR_EXTEND); setstripe_mode = (opc == SO_SETSTRIPE); + if (opc == SO_MIRROR_DELETE) { + delete = 1; + mirror_flags = MF_DESTROY; + } snprintf(cmd, sizeof(cmd), "%s %s", progname, argv[0]); progname = cmd; @@ -3242,6 +3260,12 @@ static int lfs_setstripe_internal(int argc, char **argv, migration_block = true; break; case 'C': + if (lsa.lsa_pattern == LLAPI_LAYOUT_MDT) { + fprintf(stderr, + "%s %s: -C|--overstripe-count incompatible with DoM layout\n", + progname, argv[0]); + goto usage_error; + } lsa.lsa_pattern = LLAPI_LAYOUT_OVERSTRIPING; /* fall through */ case 'c': @@ -3467,6 +3491,12 @@ static int lfs_setstripe_internal(int argc, char **argv, fprintf(stderr, "warning: '--ost-list' is " "deprecated, use '--ost' instead\n"); #endif + if (lsa.lsa_pattern == LLAPI_LAYOUT_MDT) { + fprintf(stderr, + "%s %s: -o|--ost incompatible with DoM layout\n", + progname, argv[0]); + goto usage_error; + } /* -o allows overstriping, and must note it because * parse_targets is shared with MDT striping, which * does not allow duplicates @@ -3552,6 +3582,11 @@ static int lfs_setstripe_internal(int argc, char **argv, goto usage_error; } + /* lfs migrate $filename should keep the file's layout by default */ + if (migrate_mode && !setstripe_args_specified(&lsa) && !layout && + !from_yaml) + from_copy = true; + if (xattr && !foreign_mode) { /* only print a warning as this is harmless and will be ignored */ @@ -3702,8 +3737,8 @@ static int lfs_setstripe_internal(int argc, char **argv, 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", + fprintf(stderr, "error: %s: can't specify --yaml or --copy with" + " -c, -S, -i, -o, -p or -E options.\n", argv[0]); goto error; } @@ -3715,11 +3750,11 @@ static int lfs_setstripe_internal(int argc, char **argv, goto usage_error; } - if (!comp_del && !comp_set && (opc != SO_MIRROR_SPLIT) && - comp_id != 0) { + if (!comp_del && !comp_set && opc != SO_MIRROR_SPLIT && + opc != SO_MIRROR_DELETE && comp_id != 0) { fprintf(stderr, - "%s %s: option -I can only be used with --component-del or --component-set or lfs mirror split\n", - progname, argv[0]); + "%s: option -I can only be used with --component-del or --component-set or lfs mirror split\n", + progname); goto usage_error; } @@ -3763,8 +3798,7 @@ static int lfs_setstripe_internal(int argc, char **argv, lsa.lsa_stripe_count != lsa.lsa_nr_tgts) { fprintf(stderr, "error: %s: stripe count %lld doesn't match the number of MDTs: %d\n", - progname, - (long long)lsa.lsa_stripe_count, + progname, lsa.lsa_stripe_count, lsa.lsa_nr_tgts); free(lmu); goto usage_error; @@ -3821,8 +3855,7 @@ static int lfs_setstripe_internal(int argc, char **argv, lsa.lsa_nr_tgts != lsa.lsa_stripe_count) { fprintf(stderr, "error: %s: stripe count %lld doesn't match the number of OSTs: %d\n", - argv[0], - (long long)lsa.lsa_stripe_count, + argv[0], lsa.lsa_stripe_count, lsa.lsa_nr_tgts); free(param); goto usage_error; @@ -3845,17 +3878,19 @@ static int lfs_setstripe_internal(int argc, char **argv, 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 (from_copy) { + layout = llapi_layout_get_by_path(template ?: fname, 0); + if (layout == NULL) { + fprintf(stderr, "%s: can't create composite " + "layout from file %s.\n", + progname, template ?: fname); + goto error; + } + } + if (migrate_mdt_mode) { result = llapi_migrate_mdt(fname, &migrate_mdt_param); } else if (migrate_mode) { @@ -3876,11 +3911,11 @@ static int lfs_setstripe_internal(int argc, char **argv, } else if (opc == SO_MIRROR_EXTEND) { result = mirror_extend(fname, mirror_list, mirror_flags); - } else if (opc == SO_MIRROR_SPLIT) { + } else if (opc == SO_MIRROR_SPLIT || opc == SO_MIRROR_DELETE) { if (!mirror_id && !comp_id && !lsa.lsa_pool_name) { fprintf(stderr, - "%s %s: no mirror id or component id or pool name" - " is specified\n", progname, argv[0]); + "%s: no mirror specified to delete from '%s'\n", + progname, fname); goto usage_error; } if (lsa.lsa_pool_name) @@ -4117,6 +4152,32 @@ static int lfs_find(int argc, char **argv) .name = "mirror-state", .has_arg = required_argument }, { .val = LFS_LAYOUT_FOREIGN_OPT, .name = "foreign", .has_arg = optional_argument}, + { .val = LFS_NEWERXY_OPT, + .name = "newer", .has_arg = required_argument}, + { .val = LFS_NEWERXY_OPT, + .name = "neweraa", .has_arg = required_argument}, + { .val = LFS_NEWERXY_OPT, + .name = "neweram", .has_arg = required_argument}, + { .val = LFS_NEWERXY_OPT, + .name = "newerac", .has_arg = required_argument}, + { .val = LFS_NEWERXY_OPT, + .name = "newerma", .has_arg = required_argument}, + { .val = LFS_NEWERXY_OPT, + .name = "newermm", .has_arg = required_argument}, + { .val = LFS_NEWERXY_OPT, + .name = "newermc", .has_arg = required_argument}, + { .val = LFS_NEWERXY_OPT, + .name = "newerca", .has_arg = required_argument}, + { .val = LFS_NEWERXY_OPT, + .name = "newercm", .has_arg = required_argument}, + { .val = LFS_NEWERXY_OPT, + .name = "newercc", .has_arg = required_argument}, + { .val = LFS_NEWERXY_OPT, + .name = "newerat", .has_arg = required_argument}, + { .val = LFS_NEWERXY_OPT, + .name = "newermt", .has_arg = required_argument}, + { .val = LFS_NEWERXY_OPT, + .name = "newerct", .has_arg = required_argument}, { .val = 'c', .name = "stripe-count", .has_arg = required_argument }, { .val = 'c', .name = "stripe_count", .has_arg = required_argument }, { .val = 'C', .name = "ctime", .has_arg = required_argument }, @@ -4168,6 +4229,7 @@ static int lfs_find(int argc, char **argv) /* getstripe { .val = 'v', .name = "verbose", .has_arg = no_argument }, */ /* getstripe { .val = 'y', .name = "yaml", .has_arg = no_argument }, */ { .name = NULL } }; + int optidx = 0; int pathstart = -1; int pathend = -1; int pathbad = -1; @@ -4182,7 +4244,7 @@ static int lfs_find(int argc, char **argv) /* when getopt_long_only() hits '!' it returns 1, puts "!" in optarg */ while ((c = getopt_long_only(argc, argv, "-0A:b:c:C:D:E:g:G:H:i:L:m:M:n:N:O:Ppqrs:S:t:T:u:U:vz:", - long_opts, NULL)) >= 0) { + long_opts, &optidx)) >= 0) { xtime = NULL; xsign = NULL; if (neg_opt) @@ -4404,6 +4466,130 @@ static int lfs_find(int argc, char **argv) param.fp_exclude_foreign = !!neg_opt; break; } + case LFS_NEWERXY_OPT: { + char x = 'm'; + char y = 'm'; + int xidx; + int negidx; + time_t *newery; + time_t ref = time(NULL); + + /* no need to check bad options, they won't get here */ + if (strlen(long_opts[optidx].name) == 7) { + x = long_opts[optidx].name[5]; + y = long_opts[optidx].name[6]; + } + + if (y == 't') { + static const char *const fmts[] = { + "%Y-%m-%d %H:%M:%S", + "%Y-%m-%d %H:%M", + "%Y-%m-%d", + "%H:%M:%S", /* sometime today */ + "%H:%M", + "@%s", + "%s", + NULL }; + struct tm tm; + bool found = false; + int i; + + for (i = 0; fmts[i] != NULL; i++) { + char *ptr; + + /* Init for times relative to today */ + if (strncmp(fmts[i], "%H", 2) == 0) + localtime_r(&ref, &tm); + else + memset(&tm, 0, sizeof(tm)); + ptr = strptime(optarg, fmts[i], &tm); + /* Skip spaces */ + while (ptr && isspace(*ptr)) + ptr++; + if (ptr == optarg + strlen(optarg)) { + found = true; + break; + } + } + + if (!found) { + fprintf(stderr, + "%s: invalid time '%s'\n", + progname, optarg); + fprintf(stderr, + "supported formats are:\n "); + for (i = 0; fmts[i] != NULL; i++) + fprintf(stderr, "'%s', ", + fmts[i]); + fprintf(stderr, "\n"); + ret = -EINVAL; + goto err; + } + + ref = mktime(&tm); + } else { + struct stat statbuf; + + if (stat(optarg, &statbuf) < 0) { + fprintf(stderr, + "%s: cannot stat file '%s': %s\n", + progname, optarg, + strerror(errno)); + ret = -errno; + goto err; + } + + switch (y) { + case 'a': + ref = statbuf.st_atime; + break; + case 'm': + ref = statbuf.st_mtime; + break; + case 'c': + ref = statbuf.st_ctime; + break; + default: + fprintf(stderr, + "%s: invalid Y argument: '%c'\n", + progname, x); + ret = -EINVAL; + goto err; + } + } + + switch (x) { + case 'a': + xidx = NEWERXY_ATIME; + break; + case 'm': + xidx = NEWERXY_MTIME; + break; + case 'c': + xidx = NEWERXY_CTIME; + break; + default: + fprintf(stderr, + "%s: invalid X argument: '%c'\n", + progname, x); + ret = -EINVAL; + goto err; + } + + negidx = !!neg_opt; + newery = ¶m.fp_newery[xidx][negidx]; + + if (*newery == 0) { + *newery = ref; + } else { + if (negidx) + *newery = *newery > ref ? ref : *newery; + else + *newery = *newery > ref ? *newery : ref; + } + param.fp_newerxy = 1; + break; + } case 'g': case 'G': rc = name2gid(¶m.fp_gid, optarg); @@ -5581,28 +5767,6 @@ static int mntdf(char *mntdir, char *fsname, char *pool, enum mntdf_flags flags, 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, false); - int r2 = obd_statfs_ratio(st2, false); - 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) { @@ -5615,12 +5779,9 @@ static int lfs_setdirstripe(int argc, char **argv) char *mode_opt = NULL; bool default_stripe = false; bool delete = false; - bool auto_distributed = false; bool foreign_mode = false; mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO; mode_t previous_mode = 0; - struct ll_statfs_buf *lsb = NULL; - char mntdir[PATH_MAX] = ""; char *xattr = NULL; __u32 type = LU_FOREIGN_TYPE_DAOS, flags = 0; struct option long_opts[] = { @@ -5870,7 +6031,7 @@ static int lfs_setdirstripe(int argc, char **argv) lsa.lsa_stripe_count != lsa.lsa_nr_tgts) { fprintf(stderr, "error: %s: stripe count %lld doesn't match the number of MDTs: %d\n", - argv[0], (long long)lsa.lsa_stripe_count, + argv[0], lsa.lsa_stripe_count, lsa.lsa_nr_tgts); free(param); return CMD_HELP; @@ -5881,21 +6042,6 @@ static int lfs_setdirstripe(int argc, char **argv) memcpy(param->lsp_tgts, mdts, sizeof(*mdts) * lsa.lsa_nr_tgts); } - if (!default_stripe && (lsa.lsa_pattern & LMV_HASH_FLAG_SPACE)) { - fprintf(stderr, "%s %s: can only specify -H space with -D\n", - progname, argv[0]); - free(param); - return CMD_HELP; - } - - if (param->lsp_stripe_offset != -1 && - lsa.lsa_pattern & LMV_HASH_FLAG_SPACE) { - fprintf(stderr, "%s %s: can only specify -H space with -i -1\n", - progname, argv[0]); - free(param); - return CMD_HELP; - } - dname = argv[optind]; do { if (default_stripe) { @@ -5907,100 +6053,6 @@ static int lfs_setdirstripe(int argc, char **argv) continue; } - /* - * 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; - } - - /* - * TODO: when MDT can allocate object with QoS (LU-9435), below - * code should be removed, instead we should let LMV to allocate - * the starting MDT object, and then let LOD allocate other MDT - * objects. - */ - 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; - - /* use mntdir for dirname() temporarily */ - strncpy(mntdir, dname, sizeof(mntdir) - 1); - if (!realpath(dirname(mntdir), path)) { - result = -errno; - fprintf(stderr, - "error: invalid path '%s': %s\n", - argv[optind], strerror(errno)); - break; - } - mntdir[0] = '\0'; - - result = llapi_search_mounts(path, 0, mntdir, NULL); - if (result < 0 || mntdir[0] == '\0') { - fprintf(stderr, - "No suitable Lustre mount found\n"); - break; - } - - result = mntdf(mntdir, NULL, NULL, 0, LL_STATFS_LMV, - lsb); - if (result < 0) - break; - - 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; - } - - qsort(lsb->sb_buf, lsb->sb_count, - sizeof(struct ll_statfs_data), - ll_statfs_data_comp); - - auto_distributed = true; - } - - if (auto_distributed) { - int r; - int nr = MAX(param->lsp_stripe_count, - lsb->sb_count / 2); - - /* don't use server whose usage is above 90% */ - while (nr != param->lsp_stripe_count && - obd_statfs_ratio(&lsb->sb_buf[nr].sd_st, false) > - 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); if (result) fprintf(stderr, @@ -6011,7 +6063,6 @@ static int lfs_setdirstripe(int argc, char **argv) if (mode_opt != NULL) umask(previous_mode); - free(lsb); free(param); return result; } @@ -6084,7 +6135,7 @@ static int lfs_mv(int argc, char **argv) } } - if (lmu.lum_stripe_offset == -1) { + if (lmu.lum_stripe_offset == LMV_OFFSET_DEFAULT) { fprintf(stderr, "%s mv: MDT index must be specified\n", progname); return CMD_HELP; @@ -6176,43 +6227,33 @@ static int lfs_df(int argc, char **argv) return rc; } -static int print_instance(const char *mntdir, char *fsname, size_t fsnamelen, +static int print_instance(const char *mntdir, char *buf, size_t buflen, bool opt_instance, bool opt_fsname, bool opt_mntdir) { - char *buf = fsname; - - /* llapi_search_mounts() fills "fsname", but that is not called if - * explicit paths are specified on the command-line - */ - if (opt_instance || (opt_fsname && fsname[0] == '\0')) { - int rc = llapi_getname(mntdir, fsname, fsnamelen); + int rc = 0; - if (rc < 0) { - fprintf(stderr, "cannot get instance for '%s': %s\n", - mntdir, strerror(-rc)); - return rc; - } - buf = fsname; - if (!opt_instance) { - /* print only the fsname name */ - buf = strchr(fsname, '-'); - if (buf) - *buf = '\0'; - buf = fsname; - } else if (!opt_fsname) { - /* print only the instance name */ - buf = strchr(fsname, '-'); - if (buf) - buf++; - else - buf = fsname; - } + if (opt_fsname == opt_instance) { /* both true or both false */ + rc = llapi_getname(mntdir, buf, buflen); } else if (opt_fsname) { - /* print only the fsname */ - buf = fsname; + /* llapi_search_mounts() fills @buf with fsname, but that is not + * called if explicit paths are specified on the command-line + */ + if (buf[0] == '\0') + rc = llapi_get_fsname(mntdir, buf, buflen); + } else /* if (opt_instance) */ { + rc = llapi_get_instance(mntdir, buf, buflen); } - printf("%s %s\n", buf, opt_mntdir ? mntdir : ""); + if (rc < 0) { + fprintf(stderr, "cannot get instance for '%s': %s\n", + mntdir, strerror(-rc)); + return rc; + } + + if (opt_mntdir) + printf("%s %s\n", buf, mntdir); + else + printf("%s\n", buf); return 0; } @@ -6242,10 +6283,6 @@ static int lfs_getname(int argc, char **argv) } } - /* If neither option is given, print both instance and fsname */ - if (!opt_instance && !opt_fsname) - opt_instance = opt_fsname = true; - if (optind == argc) { /* no paths specified, get all paths. */ char mntdir[PATH_MAX] = "", path[PATH_MAX] = ""; int index = 0; @@ -6468,28 +6505,41 @@ quota_type: } qctl.qc_type = qtype; break; - case 'b': - if ((dqi->dqi_bgrace = str2sec(optarg)) == ULONG_MAX) { - fprintf(stderr, "error: bad block-grace: %s\n", - optarg); - return CMD_HELP; - } - dqb->dqb_valid |= QIF_BTIME; - break; - case 'i': - if ((dqi->dqi_igrace = str2sec(optarg)) == ULONG_MAX) { - fprintf(stderr, "error: bad inode-grace: %s\n", - optarg); - return CMD_HELP; - } - dqb->dqb_valid |= QIF_ITIME; - break; - case 't': /* Yes, of course! */ - break; - default: /* getopt prints error message for us when opterr != 0 */ - return CMD_HELP; - } - } + case 'b': + if (strncmp(optarg, NOTIFY_GRACE, + strlen(NOTIFY_GRACE)) == 0) { + dqi->dqi_bgrace = NOTIFY_GRACE_TIME; + } else { + dqi->dqi_bgrace = str2sec(optarg); + if (dqi->dqi_bgrace >= NOTIFY_GRACE_TIME) { + fprintf(stderr, "error: bad " + "block-grace: %s\n", optarg); + return CMD_HELP; + } + } + dqb->dqb_valid |= QIF_BTIME; + break; + case 'i': + if (strncmp(optarg, NOTIFY_GRACE, + strlen(NOTIFY_GRACE)) == 0) { + dqi->dqi_igrace = NOTIFY_GRACE_TIME; + } else { + dqi->dqi_igrace = str2sec(optarg); + if (dqi->dqi_igrace >= NOTIFY_GRACE_TIME) { + fprintf(stderr, "error: bad " + "inode-grace: %s\n", optarg); + return CMD_HELP; + } + } + dqb->dqb_valid |= QIF_ITIME; + break; + case 't': /* Yes, of course! */ + break; + /* getopt prints error message for us when opterr != 0 */ + default: + return CMD_HELP; + } + } if (qctl.qc_type == ALLQUOTA) { fprintf(stderr, "error: neither -u, -g nor -p specified\n"); @@ -6501,12 +6551,6 @@ quota_type: return CMD_HELP; } - if ((dqb->dqb_valid | QIF_BTIME && dqi->dqi_bgrace >= UINT_MAX) || - (dqb->dqb_valid | QIF_ITIME && dqi->dqi_igrace >= UINT_MAX)) { - fprintf(stderr, "error: grace time is too large\n"); - return CMD_HELP; - } - mnt = argv[optind]; rc = llapi_quotactl(mnt, &qctl); if (rc) { @@ -6784,22 +6828,23 @@ quota_type_def: */ static char * __sec2str(time_t seconds, char *buf) { - const char spec[] = "smhdw"; - const unsigned long mult[] = {1, 60, 60*60, 24*60*60, 7*24*60*60}; - unsigned long c; - char *tail = buf; - int i; + const char spec[] = "smhdw"; + const unsigned long mult[] = {1, 60, 60*60, 24*60*60, 7*24*60*60}; + unsigned long c; + char *tail = buf; + int i; - for (i = sizeof(mult) / sizeof(mult[0]) - 1 ; i >= 0; i--) { - c = seconds / mult[i]; + for (i = ARRAY_SIZE(mult) - 1 ; i >= 0; i--) { + c = seconds / mult[i]; - if (c > 0 || (i == 0 && buf == tail)) - tail += snprintf(tail, 40-(tail-buf), "%lu%c", c, spec[i]); + if (c > 0 || (i == 0 && buf == tail)) + tail += scnprintf(tail, 40-(tail-buf), "%lu%c", c, + spec[i]); - seconds %= mult[i]; - } + seconds %= mult[i]; + } - return tail; + return tail; } static void sec2str(time_t seconds, char *buf, int rc) @@ -6977,17 +7022,23 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type, else printf(" %7s %7s %7s %7s", "-", "-", "-", "-"); printf("\n"); + } else if (qctl->qc_cmd == LUSTRE_Q_GETINFO || + qctl->qc_cmd == Q_GETOINFO) { + char bgtimebuf[40]; + char igtimebuf[40]; - } else if (qctl->qc_cmd == LUSTRE_Q_GETINFO || - qctl->qc_cmd == Q_GETOINFO) { - char bgtimebuf[40]; - char igtimebuf[40]; + if (qctl->qc_dqinfo.dqi_bgrace == NOTIFY_GRACE_TIME) + strncpy(bgtimebuf, NOTIFY_GRACE, 40); + else + sec2str(qctl->qc_dqinfo.dqi_bgrace, bgtimebuf, rc); + if (qctl->qc_dqinfo.dqi_igrace == NOTIFY_GRACE_TIME) + strncpy(igtimebuf, NOTIFY_GRACE, 40); + else + sec2str(qctl->qc_dqinfo.dqi_igrace, igtimebuf, rc); - sec2str(qctl->qc_dqinfo.dqi_bgrace, bgtimebuf, rc); - sec2str(qctl->qc_dqinfo.dqi_igrace, igtimebuf, rc); - printf("Block grace time: %s; Inode grace time: %s\n", - bgtimebuf, igtimebuf); - } + printf("Block grace time: %s; Inode grace time: %s\n", + bgtimebuf, igtimebuf); + } } static int print_obd_quota(char *mnt, struct if_quotactl *qctl, int is_mdt, @@ -7127,8 +7178,16 @@ static int get_print_quota(char *mnt, char *name, struct if_quotactl *qctl, "Some devices may be not working or deactivated. " "The data in \"[]\" is inaccurate.\n"); out: - return rc1; + if (rc1) + return rc1; + if (rc2) + return rc2; + if (rc3) + return rc3; + if (inacc) + return -EIO; + return 0; } static int lfs_project(int argc, char **argv) @@ -8322,16 +8381,10 @@ static int fill_hur_item(struct hsm_user_request *hur, unsigned int idx, hui->hui_extent.length = -1; if (mntpath != NULL) { - if (*fname == '[') - fname++; - rc = sscanf(fname, SFID, RFID(&hui->hui_fid)); - if (rc == 3) { - rc = 0; - } else { + rc = llapi_fid_parse(fname, &hui->hui_fid, NULL); + if (rc) fprintf(stderr, "hsm: '%s' is not a valid FID\n", fname); - rc = -EINVAL; - } } else { rc = lfs_hsm_prepare_file(fname, &hui->hui_fid, last_dev); } @@ -10839,6 +10892,11 @@ static int lfs_pcc_attach(int argc, char **argv) } } + if (archive_id == 0) { + fprintf(stderr, "%s: must specify attach ID\n", argv[0]); + return CMD_HELP; + } + if (argc <= optind) { fprintf(stderr, "%s: must specify one or more file names\n", argv[0]);