#include <err.h>
#include <pwd.h>
#include <grp.h>
+#include <sys/quota.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
# include <sys/quota.h>
#endif
-/* For dirname() */
-#include <libgen.h>
-
-#include <lnet/lnetctl.h>
-
-#include <liblustre.h>
-#include <lustre/lustreapi.h>
-
+#include <libcfs/libcfs.h>
#include <libcfs/libcfsutil.h>
-#include <obd.h>
-#include <obd_lov.h>
-#include "obdctl.h"
+#include <lustre/lustreapi.h>
+#include <lustre_ver.h>
/* all functions */
static int lfs_setstripe(int argc, char **argv);
" [--layout|-L]\n"
" <directory|filename> ..."},
{"setdirstripe", lfs_setdirstripe, 0,
- "To create a remote directory on a specified MDT.\n"
+ "To create a striped directory on a specified MDT. This can only\n"
+ "be done on MDT0 with the right of administrator.\n"
"usage: setdirstripe <--count|-c stripe_count>\n"
- "[--index|-i mdt_index] [--hash-type|-t hash_type]\n"
- "[--default_stripe|-D ] <dir>\n"
+ " [--index|-i mdt_index] [--hash-type|-t hash_type]\n"
+ " [--default_stripe|-D ] [--mode|-m mode] <dir>\n"
"\tstripe_count: stripe count of the striped directory\n"
"\tmdt_index: MDT index of first stripe\n"
- "\thash_type: hash type of the striped directory\n"
- "\tdefault_stripe: set default dirstripe of the directory\n"},
+ "\thash_type: hash type of the striped directory. Hash types:\n"
+ " fnv_1a_64 FNV-1a hash algorithm (default)\n"
+ " all_char sum of characters % MDT_COUNT (not recommended)\n"
+ "\tdefault_stripe: set default dirstripe of the directory\n"
+ "\tmode: the mode of the directory\n"},
{"getdirstripe", lfs_getdirstripe, 0,
"To list the striping info for a given directory\n"
"or recursively for all directories in a directory tree.\n"
" [--count|-c ] [--index|-i ] [--raw|-R]\n"
" [--recursive | -r] [ --default_stripe | -D ] <dir> "},
{"mkdir", lfs_setdirstripe, 0,
- "To create a remote directory on a specified MDT. And this can only\n"
- "be done on MDT0 by administrator.\n"
- "usage: mkdir <--index|-i mdt_index> <dir>\n"
- "\tmdt_index: MDT index of the remote directory.\n"},
+ "To create a striped directory on a specified MDT. This can only\n"
+ "be done on MDT0 with the right of administrator.\n"
+ "usage: mkdir <--count|-c stripe_count>\n"
+ " [--index|-i mdt_index] [--hash-type|-t hash_type]\n"
+ " [--default_stripe|-D ] [--mode|-m mode] <dir>\n"
+ "\tstripe_count: stripe count of the striped directory\n"
+ "\tmdt_index: MDT index of first stripe\n"
+ "\thash_type: hash type of the striped directory. Hash types:\n"
+ " fnv_1a_64 FNV-1a hash algorithm (default)\n"
+ " all_char sum of characters % MDT_COUNT (not recommended)\n"
+ "\tdefault_stripe: set default dirstripe of the directory\n"
+ "\tmode: the mode of the directory\n"},
{"rm_entry", lfs_rmentry, 0,
"To remove the name entry of the remote directory. Note: This\n"
"command will only delete the name entry, i.e. the remote directory\n"
__u64 migration_flags)
{
int fd, fdv;
- char volatile_file[PATH_MAX];
+ char volatile_file[PATH_MAX +
+ LUSTRE_VOLATILE_HDR_LEN + 4];
char parent[PATH_MAX];
char *ptr;
int rc;
else
*ptr = '\0';
}
- sprintf(volatile_file, "%s/%s::", parent, LUSTRE_VOLATILE_HDR);
+ rc = snprintf(volatile_file, sizeof(volatile_file), "%s/%s::", parent,
+ LUSTRE_VOLATILE_HDR);
+ if (rc >= sizeof(volatile_file)) {
+ rc = -E2BIG;
+ goto free;
+ }
/* create, open a volatile file, use caching (ie no directio) */
/* exclusive create is not needed because volatile files cannot
#define FIND_POOL_OPT 3
static int lfs_find(int argc, char **argv)
{
- int c, ret;
+ int c, rc;
+ int ret = 0;
time_t t;
- struct find_param param = { .maxdepth = -1, .quiet = 1 };
+ struct find_param param = {
+ .fp_max_depth = -1,
+ .quiet = 1,
+ };
struct option long_opts[] = {
{"atime", required_argument, 0, 'A'},
{"stripe-count", required_argument, 0, 'c'},
if (strcmp(optarg, "!") == 0)
neg_opt = 2;
break;
- case 'A':
- xtime = ¶m.atime;
- xsign = ¶m.asign;
- param.exclude_atime = !!neg_opt;
- /* no break, this falls through to 'C' for ctime */
- case 'C':
- if (c == 'C') {
- xtime = ¶m.ctime;
- xsign = ¶m.csign;
- param.exclude_ctime = !!neg_opt;
- }
- /* no break, this falls through to 'M' for mtime */
- case 'M':
- if (c == 'M') {
- xtime = ¶m.mtime;
- xsign = ¶m.msign;
- param.exclude_mtime = !!neg_opt;
- }
- ret = set_time(&t, xtime, optarg);
- if (ret == INT_MAX) {
- ret = -1;
- goto err;
- }
- if (ret)
- *xsign = ret;
- break;
+ case 'A':
+ xtime = ¶m.fp_atime;
+ xsign = ¶m.fp_asign;
+ param.fp_exclude_atime = !!neg_opt;
+ /* no break, this falls through to 'C' for ctime */
+ case 'C':
+ if (c == 'C') {
+ xtime = ¶m.fp_ctime;
+ xsign = ¶m.fp_csign;
+ param.fp_exclude_ctime = !!neg_opt;
+ }
+ /* no break, this falls through to 'M' for mtime */
+ case 'M':
+ if (c == 'M') {
+ xtime = ¶m.fp_mtime;
+ xsign = ¶m.fp_msign;
+ param.fp_exclude_mtime = !!neg_opt;
+ }
+ rc = set_time(&t, xtime, optarg);
+ if (rc == INT_MAX) {
+ ret = -1;
+ goto err;
+ }
+ if (rc)
+ *xsign = rc;
+ break;
case 'c':
if (optarg[0] == '+') {
param.stripecount_sign = -1;
param.check_stripecount = 1;
param.exclude_stripecount = !!neg_opt;
break;
- case 'D':
- param.maxdepth = strtol(optarg, 0, 0);
- break;
- case 'g':
- case 'G':
- ret = name2id(¶m.gid, optarg, GROUP);
- if (ret) {
- param.gid = strtoul(optarg, &endptr, 10);
+ case 'D':
+ param.fp_max_depth = strtol(optarg, 0, 0);
+ break;
+ case 'g':
+ case 'G':
+ rc = name2id(¶m.fp_gid, optarg, GROUP);
+ if (rc) {
+ param.fp_gid = strtoul(optarg, &endptr, 10);
if (*endptr != '\0') {
fprintf(stderr, "Group/GID: %s cannot "
"be found.\n", optarg);
goto err;
}
}
- param.exclude_gid = !!neg_opt;
- param.check_gid = 1;
+ param.fp_exclude_gid = !!neg_opt;
+ param.fp_check_gid = 1;
break;
case 'L':
ret = name2layout(¶m.layout, optarg);
break;
case 'u':
case 'U':
- ret = name2id(¶m.uid, optarg, USER);
- if (ret) {
- param.uid = strtoul(optarg, &endptr, 10);
+ rc = name2id(¶m.fp_uid, optarg, USER);
+ if (rc) {
+ param.fp_uid = strtoul(optarg, &endptr, 10);
if (*endptr != '\0') {
fprintf(stderr, "User/UID: %s cannot "
"be found.\n", optarg);
goto err;
}
}
- param.exclude_uid = !!neg_opt;
- param.check_uid = 1;
+ param.fp_exclude_uid = !!neg_opt;
+ param.fp_check_uid = 1;
break;
case FIND_POOL_OPT:
if (strlen(optarg) > LOV_MAXPOOLNAME) {
param.check_stripesize = 1;
param.exclude_stripesize = !!neg_opt;
break;
- case 't':
- param.exclude_type = !!neg_opt;
- switch(optarg[0]) {
- case 'b': param.type = S_IFBLK; break;
- case 'c': param.type = S_IFCHR; break;
- case 'd': param.type = S_IFDIR; break;
- case 'f': param.type = S_IFREG; break;
- case 'l': param.type = S_IFLNK; break;
- case 'p': param.type = S_IFIFO; break;
- case 's': param.type = S_IFSOCK; break;
-#ifdef S_IFDOOR /* Solaris only */
- case 'D': param.type = S_IFDOOR; break;
-#endif
- default: fprintf(stderr, "error: %s: bad type '%s'\n",
- argv[0], optarg);
- ret = CMD_HELP;
- goto err;
- };
- break;
+ case 't':
+ param.fp_exclude_type = !!neg_opt;
+ switch (optarg[0]) {
+ case 'b':
+ param.fp_type = S_IFBLK;
+ break;
+ case 'c':
+ param.fp_type = S_IFCHR;
+ break;
+ case 'd':
+ param.fp_type = S_IFDIR;
+ break;
+ case 'f':
+ param.fp_type = S_IFREG;
+ break;
+ case 'l':
+ param.fp_type = S_IFLNK;
+ break;
+ case 'p':
+ param.fp_type = S_IFIFO;
+ break;
+ case 's':
+ param.fp_type = S_IFSOCK;
+ break;
+ default:
+ fprintf(stderr, "error: %s: bad type '%s'\n",
+ argv[0], optarg);
+ ret = CMD_HELP;
+ goto err;
+ };
+ break;
default:
ret = CMD_HELP;
goto err;
pathend = argc;
}
- do {
- ret = llapi_find(argv[pathstart], ¶m);
- } while (++pathstart < pathend && !ret);
+ do {
+ rc = llapi_find(argv[pathstart], ¶m);
+ if (rc != 0 && ret == 0)
+ ret = rc;
+ } while (++pathstart < pathend);
if (ret)
fprintf(stderr, "error: %s failed for %s.\n",
};
int c, rc;
- param->maxdepth = 1;
+ param->fp_max_depth = 1;
optind = 0;
while ((c = getopt_long(argc, argv, "cdDghiLMoO:pqrRsSv",
long_opts, NULL)) != -1) {
param->quiet++;
break;
case 'd':
- param->maxdepth = 0;
+ param->fp_max_depth = 0;
break;
case 'D':
param->get_default_lmv = 1;
#endif
if (!(param->verbose & VERBOSE_DETAIL)) {
param->verbose |= VERBOSE_COUNT;
- param->maxdepth = 0;
+ param->fp_max_depth = 0;
}
break;
#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 53, 0)
case 'S':
if (!(param->verbose & VERBOSE_DETAIL)) {
param->verbose |= VERBOSE_SIZE;
- param->maxdepth = 0;
+ param->fp_max_depth = 0;
}
break;
#if LUSTRE_VERSION_CODE < OBD_OCD_VERSION(2, 9, 53, 0)
#endif
if (!(param->verbose & VERBOSE_DETAIL)) {
param->verbose |= VERBOSE_OFFSET;
- param->maxdepth = 0;
+ param->fp_max_depth = 0;
}
break;
case 'p':
if (!(param->verbose & VERBOSE_DETAIL)) {
param->verbose |= VERBOSE_POOL;
- param->maxdepth = 0;
+ param->fp_max_depth = 0;
}
break;
case 'g':
if (!(param->verbose & VERBOSE_DETAIL)) {
param->verbose |= VERBOSE_GENERATION;
- param->maxdepth = 0;
+ param->fp_max_depth = 0;
}
break;
case 'L':
if (!(param->verbose & VERBOSE_DETAIL)) {
param->verbose |= VERBOSE_LAYOUT;
- param->maxdepth = 0;
+ param->fp_max_depth = 0;
}
break;
case 'M':
if (!(param->verbose & VERBOSE_DETAIL))
- param->maxdepth = 0;
+ param->fp_max_depth = 0;
param->verbose |= VERBOSE_MDTINDEX;
break;
case 'R':
return CMD_HELP;
if (param->recursive)
- param->maxdepth = -1;
+ param->fp_max_depth = -1;
if (!param->verbose)
param->verbose = VERBOSE_ALL;
char *stripe_offset_opt = NULL;
char *stripe_count_opt = NULL;
char *stripe_hash_opt = NULL;
+ char *mode_opt = NULL;
int default_stripe = 0;
+ mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO;
+ mode_t previous_mode = 0;
struct option long_opts[] = {
{"count", required_argument, 0, 'c'},
{"index", required_argument, 0, 'i'},
+ {"mode", required_argument, 0, 'm'},
{"hash-type", required_argument, 0, 't'},
- {"default_stripe", required_argument, 0, 'D'},
+ {"default_stripe", no_argument, 0, 'D'},
{0, 0, 0, 0}
};
optind = 0;
- while ((c = getopt_long(argc, argv, "c:Di:t:", long_opts, NULL)) >= 0) {
+ while ((c = getopt_long(argc, argv, "c:Di:m:t:", long_opts,
+ NULL)) >= 0) {
switch (c) {
case 0:
/* Long options. */
case 'i':
stripe_offset_opt = optarg;
break;
+ case 'm':
+ mode_opt = optarg;
+ break;
case 't':
stripe_hash_opt = optarg;
break;
}
}
+ if (mode_opt != NULL) {
+ mode = strtoul(mode_opt, &end, 8);
+ if (*end != '\0') {
+ fprintf(stderr, "error: %s: bad mode '%s'\n",
+ argv[0], mode_opt);
+ return CMD_HELP;
+ }
+ previous_mode = umask(0);
+ }
+
if (stripe_hash_opt == NULL ||
strcmp(stripe_hash_opt, LMV_HASH_NAME_FNV_1A_64) == 0) {
hash_type = LMV_HASH_TYPE_FNV_1A_64;
stripe_offset, stripe_count,
hash_type, NULL);
} else {
- result = llapi_dir_create_pool(dname, 0, stripe_offset,
+ result = llapi_dir_create_pool(dname, mode,
+ stripe_offset,
stripe_count, hash_type,
NULL);
}
dname = argv[++optind];
} while (dname != NULL);
+ if (mode_opt != NULL)
+ umask(previous_mode);
+
return result;
}
static int lfs_mv(int argc, char **argv)
{
- struct find_param param = { .maxdepth = -1, .mdtindex = -1};
+ struct find_param param = {
+ .fp_max_depth = -1,
+ .mdtindex = -1,
+ };
char *end;
int c;
int rc = 0;
double ratio = 0;
char *suffix = "KMGTPEZY";
/* Note if we have >2^64 bytes/fs these buffers will need to be grown */
- char tbuf[20], ubuf[20], abuf[20], rbuf[20];
+ 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;
return rc;
}
- rc = llapi_target_iterate(num_types, obd_types,
- mntdir, llapi_ping_target);
-
+ rc = llapi_target_check(num_types, obd_types, mntdir);
if (rc)
fprintf(stderr, "error: %s: %s status failed\n",
argv[0],argv[1]);
sprintf(buf, LPU64, num);
} else {
if (num >> 30)
- sprintf(buf, LPU64"%s", num >> 30, "T");
+ sprintf(buf, "%5.4gT", (double)num / (1 << 30));
else if (num >> 20)
- sprintf(buf, LPU64"%s", num >> 20, "G");
+ sprintf(buf, "%5.4gG", (double)num / (1 << 20));
else if (num >> 10)
- sprintf(buf, LPU64"%s", num >> 10, "M");
+ sprintf(buf, "%5.4gM", (double)num / (1 << 10));
else
- sprintf(buf, LPU64"%s", num, "K");
+ sprintf(buf, LPU64"%s", num, "k");
}
}
char strbuf[32];
if (dqb->dqb_bhardlimit &&
- toqb(dqb->dqb_curspace) >= dqb->dqb_bhardlimit) {
+ lustre_stoqb(dqb->dqb_curspace) >= dqb->dqb_bhardlimit) {
bover = 1;
} else if (dqb->dqb_bsoftlimit && dqb->dqb_btime) {
if (dqb->dqb_btime > now) {
if (bover)
diff2str(dqb->dqb_btime, timebuf, now);
- kbytes2str(toqb(dqb->dqb_curspace), strbuf, h);
+ kbytes2str(lustre_stoqb(dqb->dqb_curspace), strbuf, h);
if (rc == -EREMOTEIO)
sprintf(numbuf[0], "%s*", strbuf);
else
break;
case 'o':
valid = qctl.qc_valid = QC_UUID;
- strncpy(obd_uuid, optarg, sizeof(qctl.obd_uuid));
+ strlcpy(obd_uuid, optarg, sizeof(qctl.obd_uuid));
break;
case 'i':
valid = qctl.qc_valid = QC_MDTIDX;
verbose) {
char strbuf[32];
- kbytes2str(total_balloc, strbuf, human_readable);
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);
}
static int lfs_flushctx(int argc, char **argv)
{
- int kdestroy = 0, c;
- FILE *proc = NULL;
- char procline[PATH_MAX], *line;
- int rc = 0;
+ int kdestroy = 0, c;
+ char mntdir[PATH_MAX] = {'\0'};
+ int index = 0;
+ int rc = 0;
optind = 0;
while ((c = getopt(argc, argv, "k")) != -1) {
}
if (kdestroy) {
- int rc;
if ((rc = system("kdestroy > /dev/null")) != 0) {
rc = WEXITSTATUS(rc);
fprintf(stderr, "error destroying tickets: %d, continuing\n", rc);
}
}
- if (optind >= argc) {
- /* flush for all mounted lustre fs. */
- proc = fopen("/proc/mounts", "r");
- if (!proc) {
- fprintf(stderr, "error: %s: can't open /proc/mounts\n",
- argv[0]);
- return -1;
- }
-
- while ((line = fgets(procline, PATH_MAX, proc)) != NULL) {
- char dev[PATH_MAX];
- char mp[PATH_MAX];
- char fs[PATH_MAX];
+ if (optind >= argc) {
+ /* flush for all mounted lustre fs. */
+ while (!llapi_search_mounts(NULL, index++, mntdir, NULL)) {
+ /* Check if we have a mount point */
+ if (mntdir[0] == '\0')
+ continue;
- if (sscanf(line, "%s %s %s", dev, mp, fs) != 3) {
- fprintf(stderr, "%s: unexpected format in "
- "/proc/mounts\n",
- argv[0]);
+ if (flushctx_ioctl(mntdir))
rc = -1;
- goto out;
- }
-
- if (strcmp(fs, "lustre") != 0)
- continue;
- /* we use '@' to determine it's a client. are there
- * any other better way?
- */
- if (strchr(dev, '@') == NULL)
- continue;
- if (flushctx_ioctl(mp))
- rc = -1;
- }
+ mntdir[0] = '\0'; /* avoid matching in next loop */
+ }
} else {
/* flush fs as specified */
while (optind < argc) {
rc = -1;
}
}
-
-out:
- if (proc != NULL)
- fclose(proc);
return rc;
}
/* namespace rec includes parent and filename */
printf(" p="DFID" %.*s", PFID(&rec->cr_pfid),
rec->cr_namelen, rec->cr_name);
- if (fid_is_sane(&rec->cr_sfid))
+
+ if (!fid_is_zero(&rec->cr_sfid))
printf(" s="DFID" sp="DFID" %.*s",
PFID(&rec->cr_sfid), PFID(&rec->cr_spfid),
changelog_rec_snamelen(rec),
device = argv[optind++];
path = calloc(1, PATH_MAX);
+ if (path == NULL) {
+ fprintf(stderr, "error: Not enough memory\n");
+ return -errno;
+ }
rc = 0;
while (optind < argc) {
if ((hps == HPS_RUNNING) &&
(hua == HUA_ARCHIVE || hua == HUA_RESTORE))
printf("("LPX64 " bytes moved)\n", he.length);
- else if ((he.offset + he.length) == OBD_OBJECT_EOF)
+ else if ((he.offset + he.length) == LUSTRE_EOF)
printf("(from "LPX64 " to EOF)\n", he.offset);
else
printf("(from "LPX64 " to "LPX64")\n",
/* If allocated buffer was too small, gets something
* bigger */
if (nbfile_alloc <= hur->hur_request.hr_itemcount) {
+ ssize_t size;
nbfile_alloc = nbfile_alloc * 2 + 1;
oldhur = hur;
hur = llapi_hsm_user_request_alloc(nbfile_alloc,
strerror(errno));
hur = oldhur;
rc = -errno;
+ fclose(fp);
+ goto out_free;
+ }
+ size = hur_len(oldhur);
+ if (size < 0) {
+ fprintf(stderr, "Cannot allocate "
+ "the requested size\n");
+ hur = oldhur;
+ rc = -E2BIG;
+ fclose(fp);
goto out_free;
}
- memcpy(hur, oldhur, hur_len(oldhur));
+ memcpy(hur, oldhur, size);
free(oldhur);
}
rc = lfs_hsm_prepare_file(line, &hui->hui_fid,
&last_dev);
hur->hur_request.hr_itemcount++;
- if (rc)
+ if (rc) {
+ fclose(fp);
goto out_free;
+ }
if ((some_file[0] == '\0') &&
(strlen(line) < sizeof(some_file)))
setlinebuf(stdout);
- ptl_initialize(argc, argv);
- if (obd_initialize(argc, argv) < 0)
- exit(2);
-
Parser_init("lfs > ", cmdlist);
if (argc > 1) {
rc = Parser_commands();
}
- obd_finalize(argc, argv);
return rc < 0 ? -rc : rc;
}
+#ifdef _LUSTRE_IDL_H_
+/* Everything we need here should be included by lustreapi.h. */
+# error "lfs should not depend on lustre_idl.h"
+#endif /* _LUSTRE_IDL_H_ */