X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Futils%2Flfs.c;h=90cbfa0a44559ef3f89233237fd2425bc2380e40;hp=c58113de855936ee452991cf107e8eb1d9852ba0;hb=72ac681d5d686d5626be606cc87ddeeed0b8e3a0;hpb=a99e42c9fa47677cd2468abfa9378d776cc40803;ds=sidebyside diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index c58113d..90cbfa0 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -27,7 +27,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2014, Intel Corporation. + * Copyright (c) 2011, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -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) \ @@ -356,17 +361,40 @@ command_t cmdlist[] = { {"swap_layouts", lfs_swap_layouts, 0, "Swap layouts between 2 files.\n" "usage: swap_layouts "}, {"migrate", lfs_setstripe, 0, - "migrate file/directory between MDTs, or migrate file from one OST " + "migrate a directory between MDTs.\n" + "usage: migrate --mdt-index [--verbose|-v] " + "\n" + "\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 [--mdt-index|-m ] ]\n" - "\tmdt_idx: MDT index to migrate to\n" - " or\n" - MIGRATE_USAGE}, + "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" + "\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" + "\tpool_name: name of the predefined pool of OSTs\n" + "\tost_indices: OSTs to stripe over, in order\n" + "\tblock: wait for the operation to return before continuing\n" + "\tnon-block: do not wait for the operation to return.\n"}, {"mv", lfs_mv, 0, "To move directories between MDTs. This command is deprecated, " "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"}, @@ -623,9 +651,13 @@ static int lfs_migrate(char *name, __u64 migration_flags, { int fd = -1; int fdv = -1; - char volatile_file[PATH_MAX + - LUSTRE_VOLATILE_HDR_LEN + 4]; char parent[PATH_MAX]; + int mdt_index; + int random_value; + char volatile_file[sizeof(parent) + + LUSTRE_VOLATILE_HDR_LEN + + 2 * sizeof(mdt_index) + + 2 * sizeof(random_value) + 4]; char *ptr; int rc; struct lov_user_md *lum = NULL; @@ -699,18 +731,29 @@ static int lfs_migrate(char *name, __u64 migration_flags, *ptr = '\0'; } - rc = snprintf(volatile_file, sizeof(volatile_file), "%s/%s::", parent, - LUSTRE_VOLATILE_HDR); - if (rc >= sizeof(volatile_file)) { - rc = -E2BIG; + rc = llapi_file_fget_mdtidx(fd, &mdt_index); + if (rc < 0) { + fprintf(stderr, "%s: %s: cannot get MDT index: %s\n", + progname, name, strerror(-rc)); goto error; } - /* create, open a volatile file, use caching (ie no directio) */ - /* exclusive create is not needed because volatile files cannot - * conflict on name by construction */ - fdv = llapi_file_open_param(volatile_file, O_CREAT | O_WRONLY, 0644, - param); + do { + random_value = random(); + rc = snprintf(volatile_file, sizeof(volatile_file), + "%s/%s:%.4X:%.4X", parent, LUSTRE_VOLATILE_HDR, + mdt_index, random_value); + if (rc >= sizeof(volatile_file)) { + rc = -E2BIG; + goto error; + } + + /* create, open a volatile file, use caching (ie no directio) */ + fdv = llapi_file_open_param(volatile_file, + O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, + S_IRUSR | S_IWUSR, param); + } while (fdv == -EEXIST); + if (fdv < 0) { rc = fdv; fprintf(stderr, "%s: %s: cannot create volatile file in" @@ -926,6 +969,8 @@ static int lfs_setstripe(int argc, char **argv) #endif {"stripe-size", required_argument, 0, 'S'}, {"stripe_size", required_argument, 0, 'S'}, + /* --verbose is only valid in migrate mode */ + {"verbose", no_argument, 0, 'v'}, {0, 0, 0, 0} }; @@ -936,7 +981,7 @@ static int lfs_setstripe(int argc, char **argv) if (strcmp(argv[0], "migrate") == 0) migrate_mode = true; - while ((c = getopt_long(argc, argv, "bc:di:m:no:p:s:S:", + while ((c = getopt_long(argc, argv, "bc:di:m:no:p:s:S:v", long_opts, NULL)) >= 0) { switch (c) { case 0: @@ -1013,6 +1058,14 @@ static int lfs_setstripe(int argc, char **argv) case 'p': pool_name_arg = optarg; break; + case 'v': + if (!migrate_mode) { + fprintf(stderr, "--verbose is valid only for" + " migrate mode\n"); + return CMD_HELP; + } + migrate_mdt_param.fp_verbose = VERBOSE_DETAIL; + break; default: return CMD_HELP; } @@ -2902,22 +2955,29 @@ static void print_quota_title(char *name, struct if_quotactl *qctl, "files", "quota", "limit", "grace"); } -static void kbytes2str(__u64 num, char *buf, bool h) +static void kbytes2str(__u64 num, char *buf, int buflen, bool h) { if (!h) { - sprintf(buf, LPU64, num); + snprintf(buf, buflen, "%ju", (uintmax_t)num); } else { - if (num >> 30) - sprintf(buf, "%5.4gT", (double)num / (1 << 30)); + if (num >> 40) + snprintf(buf, buflen, "%5.4gP", + (double)num / ((__u64)1 << 40)); + else if (num >> 30) + snprintf(buf, buflen, "%5.4gT", + (double)num / (1 << 30)); else if (num >> 20) - sprintf(buf, "%5.4gG", (double)num / (1 << 20)); + snprintf(buf, buflen, "%5.4gG", + (double)num / (1 << 20)); else if (num >> 10) - sprintf(buf, "%5.4gM", (double)num / (1 << 10)); + snprintf(buf, buflen, "%5.4gM", + (double)num / (1 << 10)); else - sprintf(buf, LPU64"%s", num, "k"); + snprintf(buf, buflen, "%ju%s", (uintmax_t)num, "k"); } } +#define STRBUF_LEN 32 static void print_quota(char *mnt, struct if_quotactl *qctl, int type, int rc, bool h) { @@ -2928,9 +2988,9 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type, if (qctl->qc_cmd == LUSTRE_Q_GETQUOTA || qctl->qc_cmd == Q_GETOQUOTA) { int bover = 0, iover = 0; struct obd_dqblk *dqb = &qctl->qc_dqblk; - char numbuf[3][32]; + char numbuf[3][STRBUF_LEN]; char timebuf[40]; - char strbuf[32]; + char strbuf[STRBUF_LEN]; if (dqb->dqb_bhardlimit && lustre_stoqb(dqb->dqb_curspace) >= dqb->dqb_bhardlimit) { @@ -2963,21 +3023,22 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type, if (bover) diff2str(dqb->dqb_btime, timebuf, now); - kbytes2str(lustre_stoqb(dqb->dqb_curspace), strbuf, h); + kbytes2str(lustre_stoqb(dqb->dqb_curspace), + strbuf, sizeof(strbuf), h); if (rc == -EREMOTEIO) sprintf(numbuf[0], "%s*", strbuf); else sprintf(numbuf[0], (dqb->dqb_valid & QIF_SPACE) ? "%s" : "[%s]", strbuf); - kbytes2str(dqb->dqb_bsoftlimit, strbuf, h); + kbytes2str(dqb->dqb_bsoftlimit, strbuf, sizeof(strbuf), h); if (type == QC_GENERAL) sprintf(numbuf[1], (dqb->dqb_valid & QIF_BLIMITS) ? "%s" : "[%s]", strbuf); else sprintf(numbuf[1], "%s", "-"); - kbytes2str(dqb->dqb_bhardlimit, strbuf, h); + kbytes2str(dqb->dqb_bhardlimit, strbuf, sizeof(strbuf), h); sprintf(numbuf[2], (dqb->dqb_valid & QIF_BLIMITS) ? "%s" : "[%s]", strbuf); @@ -2989,16 +3050,17 @@ static void print_quota(char *mnt, struct if_quotactl *qctl, int type, diff2str(dqb->dqb_itime, timebuf, now); sprintf(numbuf[0], (dqb->dqb_valid & QIF_INODES) ? - LPU64 : "["LPU64"]", dqb->dqb_curinodes); + "%ju" : "[%ju]", (uintmax_t)dqb->dqb_curinodes); if (type == QC_GENERAL) sprintf(numbuf[1], (dqb->dqb_valid & QIF_ILIMITS) ? - LPU64 : "["LPU64"]", dqb->dqb_isoftlimit); + "%ju" : "[%ju]", + (uintmax_t)dqb->dqb_isoftlimit); else sprintf(numbuf[1], "%s", "-"); sprintf(numbuf[2], (dqb->dqb_valid & QIF_ILIMITS) ? - LPU64 : "["LPU64"]", dqb->dqb_ihardlimit); + "%ju" : "[%ju]", (uintmax_t)dqb->dqb_ihardlimit); if (type != QC_OSTIDX) printf(" %7s%c %6s %7s %7s", @@ -3202,15 +3264,17 @@ ug_output: if (qctl.qc_valid == QC_GENERAL && qctl.qc_cmd != LUSTRE_Q_GETINFO && verbose) { - char strbuf[32]; + char strbuf[STRBUF_LEN]; rc2 = print_obd_quota(mnt, &qctl, 1, human_readable, &total_ialloc); rc3 = print_obd_quota(mnt, &qctl, 0, human_readable, &total_balloc); - kbytes2str(total_balloc, strbuf, human_readable); - printf("Total allocated inode limit: "LPU64", total " - "allocated block limit: %s\n", total_ialloc, strbuf); + kbytes2str(total_balloc, strbuf, sizeof(strbuf), + human_readable); + printf("Total allocated inode limit: %ju, total " + "allocated block limit: %s\n", (uintmax_t)total_ialloc, + strbuf); } if (rc1 || rc2 || rc3 || inacc) @@ -3390,8 +3454,8 @@ static int lfs_changelog(int argc, char **argv) secs = rec->cr_time >> 30; gmtime_r(&secs, &ts); - printf(LPU64" %02d%-5s %02d:%02d:%02d.%06d %04d.%02d.%02d " - "0x%x t="DFID, rec->cr_index, rec->cr_type, + printf("%ju %02d%-5s %02d:%02d:%02d.%06d %04d.%02d.%02d " + "0x%x t="DFID, (uintmax_t) rec->cr_index, rec->cr_type, changelog_type2str(rec->cr_type), ts.tm_hour, ts.tm_min, ts.tm_sec, (int)(rec->cr_time & ((1<<30) - 1)), @@ -3655,7 +3719,7 @@ static int lfs_data_version(int argc, char **argv) if (rc < 0) err(errno, "cannot get version for %s", path); else - printf(LPU64 "\n", data_version); + printf("%ju" "\n", (uintmax_t)data_version); close(fd); return rc; @@ -4168,6 +4232,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;