#include <libcfs/util/string.h>
#include <libcfs/util/ioctl.h>
#include <libcfs/util/parser.h>
+#include <libcfs/util/string.h>
#include <lustre/lustreapi.h>
#include <linux/lustre/lustre_ver.h>
#include <linux/lustre/lustre_param.h>
" [--stripe-index|-i <start_ost_idx>]\n" \
" [--stripe-size|-S <stripe_size>]\n" \
" [--layout|-L <pattern>]\n" \
- " [--pool|-p <pool_name>]\n" \
+ " [--mirror_count|-N[mirror_count]]\n" \
" [--ost|-o <ost_indices>]\n" \
+ " [--pool|-p <pool_name>]\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" \
"\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" \
"\t -o <ost_1>,<ost_i>-<ost_j>,<ost_n>\n" \
"\t Or:\n" \
"\t -o <ost_1> -o <ost_i>-<ost_j> -o <ost_n>\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" \
"\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" \
"\t file.\n"
#define MIRROR_EXTEND_USAGE \
- " <--mirror-count|-N[mirror_count]>\n" \
- " [setstripe options|-f <victim_file>]\n" \
+ " {--mirror-count|-N[mirror_count]}\n" \
+ " [SETSTRIPE_OPTIONS|-f|--file <victim_file>]\n" \
" [--no-verify]\n"
#define SETSTRIPE_USAGE \
"\tmode: the file access permission of the directory (octal)\n" \
"To create dir with a foreign (free format) layout :\n" \
"setdirstripe|mkdir --foreign[=<foreign_type>] -x|-xattr <string> " \
- "[--mode|-m mode] [--flags <hex>] <dir>\n" \
+ "[--mode|-o mode] [--flags <hex>] <dir>\n" \
"\tmode: the mode of the directory\n" \
"\tforeign_type: none or daos\n"
.pc_help = "Create a mirrored file.\n"
"usage: lfs mirror create "
"<--mirror-count|-N[mirror_count]> "
- "[setstripe options] ... <filename|directory> ...\n"
+ "[SETSTRIPE_OPTIONS] ... <filename|directory> ...\n"
MIRROR_CREATE_HELP },
{ .pc_name = "delete", .pc_func = lfs_mirror_delete,
.pc_help = "delete a mirror from a file.\n"
.pc_help = "Extend a mirrored file.\n"
"usage: lfs mirror extend "
"<--mirror-count|-N[mirror_count]> [--no-verify] "
- "[setstripe options|-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"
SSM_CMD_COMMON("setstripe --component-add")
SSM_HELP_COMMON
"To totally delete the default striping from an existing directory:\n"
- "usage: setstripe -d <directory>\n"
+ "usage: setstripe [--delete|-d] <directory>\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] <directory|filename>\n"
+ "usage: setstripe {--mirror-count|-N}[mirror_count] [SETSTRIPE_OPTIONS] <directory|filename>\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"
" [[!] --component-count [+-]<comp_cnt>]\n"
" [[!] --component-start [+-]N[kMGTPE]]\n"
" [[!] --component-end|-E [+-]N[kMGTPE]]\n"
- " [[!] --component-flags <comp_flags>]\n"
+ " [[!] --component-flags {init,stale,prefer,offline,nosync,extension}]\n"
" [[!] --mirror-count|-N [+-]<n>]\n"
" [[!] --mirror-state <[^]state>]\n"
" [[!] --mdt-count|-T [+-]<stripes>]\n"
{"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 <fsname>[.<pool>] [path]"},
+ "Usage: df [--inodes|-i] [--human-readable|-h] [--lazy|-l]\n"
+ " [--pool|-p <fsname>[.<pool>]] [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 ...]"},
" [--inode-softlimit <inode-softlimit>]\n"
" [--inode-hardlimit <inode-hardlimit>] <filesystem>\n"
" setquota [-t] <-u|--user|-g|--group|-p|--projid>\n"
- " [--block-grace <block-grace>]\n"
- " [--inode-grace <inode-grace>] <filesystem>\n"
+ " [--block-grace 'notify'|<block-grace>]\n"
+ " [--inode-grace 'notify'|<inode-grace>] <filesystem>\n"
" setquota <-U|-G|-P>\n"
" -b <block-softlimit> -B <block-hardlimit>\n"
" -i <inode-softlimit> -I <inode-hardlimit> <filesystem>\n"
" 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 <obd_uuid>|-i <mdt_idx>|-I "
"<ost_idx>]\n"
" [<-u|-g|-p> <uname>|<uid>|<gname>|<gid>|<projid>] <filesystem>\n"
{"rmfid", lfs_rmfid, 0, "Remove file(s) by FID(s)\n"
"usage: rmfid <fsname|rootpath> <fid> ..."},
{"data_version", lfs_data_version, 0, "Display file data version for "
- "a given path.\n" "usage: data_version -[n|r|w] <path>"},
+ "a given path.\n" "usage: data_version [-n|-r|-w] <path>"},
{"hsm_state", lfs_hsm_state, 0, "Display the HSM information (states, "
"undergoing actions) for given files.\n usage: hsm_state <file> ..."},
{"hsm_set", lfs_hsm_set, 0, "Set HSM user flag on specified files.\n"
}
/* 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) {
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':
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
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
*/
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;
}
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) {
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;
}
}
}
- /* 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;
}
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");
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) {
*/
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)
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,