X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;ds=inline;f=lustre%2Futils%2Flfs.c;h=60bdab6ba09f8a2c96453abf5497464359d47a3a;hb=14de1a415da53d341b378c4722aef2ec16b066ad;hp=1dcfc448f999473e088b4327454c81a0b3b03ca9;hpb=4a0ec1d7621cc42e3139d067969e37b8285f7c06;p=fs%2Flustre-release.git diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 1dcfc44..60bdab6 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -75,6 +75,10 @@ #include #include +#ifndef ARRAY_SIZE +# define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof((a)[0]))) +#endif /* !ARRAY_SIZE */ + /* all functions */ static int lfs_setstripe(int argc, char **argv); static int lfs_find(int argc, char **argv); @@ -116,6 +120,7 @@ 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); +static int lfs_ladvise(int argc, char **argv); /* Setstripe and migrate share mostly the same parameters */ #define SSM_CMD_COMMON(cmd) \ @@ -359,19 +364,19 @@ command_t cmdlist[] = { "migrate a directory between MDTs.\n" "usage: migrate --mdt-index [--verbose|-v] " "\n" - "\tmdt_idx: index of the destination MDT\n"}, - {"migrate", lfs_setstripe, 0, + "\tmdt_idx: index of the destination MDT\n" + "\n" "migrate file objects from one OST " "layout\nto another (may be not safe with concurent writes).\n" - "usage: migrate " + "usage: migrate " "[--stripe-count|-c] \n" - "[--stripe-index|-i] \n" - "[--stripe-size|-S] \n" - "[--pool|-p] \n" - "[--ost-list|-o] \n" - "[--block|-b]\n" - "[--non-block|-n]\n" - "\n" + " [--stripe-index|-i] \n" + " [--stripe-size|-S] \n" + " [--pool|-p] \n" + " [--ost-list|-o] \n" + " [--block|-b]\n" + " [--non-block|-n]\n" + " \n" "\tstripe_count: number of OSTs to stripe a file over\n" "\tstripe_ost_index: index of the first OST to stripe a file over\n" "\tstripe_size: number of bytes to store before moving to the next OST\n" @@ -384,6 +389,12 @@ command_t cmdlist[] = { "use \"migrate\" instead.\n" "usage: mv [--mdt-index|-M] " "[--verbose|-v]\n"}, + {"ladvise", lfs_ladvise, 0, + "Provide servers with advice about access patterns for a file.\n" + "usage: ladvise [--advice|-a ADVICE] [--start|-s START[kMGT]]\n" + " [--background|-b]\n" + " {[--end|-e END[kMGT]] | [--length|-l LENGTH[kMGT]]}\n" + " ..."}, {"help", Parser_help, 0, "help"}, {"exit", Parser_quit, 0, "quit"}, {"quit", Parser_quit, 0, "quit"}, @@ -1213,10 +1224,11 @@ static int lfs_setstripe(int argc, char **argv) /* Save the first error encountered. */ if (result2 == 0) result2 = result; - fprintf(stderr, - "error: %s: %s file '%s' failed\n", + fprintf(stderr, "error: %s: %s file '%s' failed: %s\n", argv[0], migrate_mode ? "migrate" : "create", - fname); + fname, + pool_name_arg != NULL && result == EINVAL ? + "OST not in pool?" : strerror(result)); continue; } } @@ -4221,6 +4233,178 @@ static int lfs_swap_layouts(int argc, char **argv) SWAP_LAYOUTS_KEEP_ATIME); } +static const char *const ladvise_names[] = LU_LADVISE_NAMES; + +static enum lu_ladvise_type lfs_get_ladvice(const char *string) +{ + enum lu_ladvise_type advice; + + for (advice = 0; + advice < ARRAY_SIZE(ladvise_names); advice++) { + if (ladvise_names[advice] == NULL) + continue; + if (strcmp(string, ladvise_names[advice]) == 0) + return advice; + } + + return LU_LADVISE_INVALID; +} + +static int lfs_ladvise(int argc, char **argv) +{ + struct option long_opts[] = { + {"advice", required_argument, 0, 'a'}, + {"background", no_argument, 0, 'b'}, + {"end", required_argument, 0, 'e'}, + {"start", required_argument, 0, 's'}, + {"length", required_argument, 0, 'l'}, + {0, 0, 0, 0} + }; + char short_opts[] = "a:be:l:s:"; + int c; + int rc = 0; + const char *path; + int fd; + struct lu_ladvise advice; + enum lu_ladvise_type advice_type = LU_LADVISE_INVALID; + unsigned long long start = 0; + unsigned long long end = LUSTRE_EOF; + unsigned long long length = 0; + unsigned long long size_units; + unsigned long long flags = 0; + + optind = 0; + while ((c = getopt_long(argc, argv, short_opts, + long_opts, NULL)) != -1) { + switch (c) { + case 'a': + advice_type = lfs_get_ladvice(optarg); + if (advice_type == LU_LADVISE_INVALID) { + fprintf(stderr, "%s: invalid advice type " + "'%s'\n", argv[0], optarg); + fprintf(stderr, "Valid types:"); + + for (advice_type = 0; + advice_type < ARRAY_SIZE(ladvise_names); + advice_type++) { + if (ladvise_names[advice_type] == NULL) + continue; + fprintf(stderr, " %s", + ladvise_names[advice_type]); + } + fprintf(stderr, "\n"); + + return CMD_HELP; + } + break; + case 'b': + flags |= LF_ASYNC; + break; + case 'e': + size_units = 1; + rc = llapi_parse_size(optarg, &end, + &size_units, 0); + if (rc) { + fprintf(stderr, "%s: bad end offset '%s'\n", + argv[0], optarg); + return CMD_HELP; + } + break; + case 's': + size_units = 1; + rc = llapi_parse_size(optarg, &start, + &size_units, 0); + if (rc) { + fprintf(stderr, "%s: bad start offset " + "'%s'\n", argv[0], optarg); + return CMD_HELP; + } + break; + case 'l': + size_units = 1; + rc = llapi_parse_size(optarg, &length, + &size_units, 0); + if (rc) { + fprintf(stderr, "%s: bad length '%s'\n", + argv[0], optarg); + return CMD_HELP; + } + break; + case '?': + return CMD_HELP; + default: + fprintf(stderr, "%s: option '%s' unrecognized\n", + argv[0], argv[optind - 1]); + return CMD_HELP; + } + } + + if (advice_type == LU_LADVISE_INVALID) { + fprintf(stderr, "%s: please give an advice type\n", argv[0]); + fprintf(stderr, "Valid types:"); + for (advice_type = 0; advice_type < ARRAY_SIZE(ladvise_names); + advice_type++) { + if (ladvise_names[advice_type] == NULL) + continue; + fprintf(stderr, " %s", ladvise_names[advice_type]); + } + fprintf(stderr, "\n"); + return CMD_HELP; + } + + if (argc <= optind) { + fprintf(stderr, "%s: please give one or more file names\n", + argv[0]); + return CMD_HELP; + } + + if (end != LUSTRE_EOF && length != 0 && end != start + length) { + fprintf(stderr, "%s: conflicting arguments of -l and -e\n", + argv[0]); + return CMD_HELP; + } + + if (end == LUSTRE_EOF && length != 0) + end = start + length; + + if (end <= start) { + fprintf(stderr, "%s: range [%llu, %llu] is invalid\n", + argv[0], start, end); + return CMD_HELP; + } + + while (optind < argc) { + int rc2; + + path = argv[optind++]; + + fd = open(path, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "%s: cannot open file '%s': %s\n", + argv[0], path, strerror(errno)); + rc2 = -errno; + goto next; + } + + advice.lla_start = start; + advice.lla_end = end; + advice.lla_advice = advice_type; + advice.lla_padding = 0; + rc2 = llapi_ladvise(fd, flags, 1, &advice); + close(fd); + if (rc2 < 0) { + fprintf(stderr, "%s: cannot give advice '%s' to file " + "'%s': %s\n", argv[0], + ladvise_names[advice_type], + path, strerror(errno)); + } +next: + if (rc == 0 && rc2 < 0) + rc = rc2; + } + return rc; +} + int main(int argc, char **argv) { int rc;